In my Application_Start
I configure Unity using the Unity-AutoRegistration tool:
UnityFactory.Configure(config => config
.Include(If.ImplementsITypeName, Then.Register())
.ExcludeSystemAssemblies()
);
My UnityFactory
class is static. Configure
works as follows:
public static void Configure(Func<IAutoRegistration,IAutoRegistration> configuration)
{
// Store the configuration to be able to apply it again when needed
UnityFactory.configuration = configuration;
// Create new UnityContainer
container = new UnityContainer();
// Apply configuration
configuration(container.ConfigureAutoRegistration()).ApplyAutoRegistration();
}
It runs under IIS7 and all works fine when when it's started.
It stops working whenever the application pool has been recycled. The configuration somehow gets messed up, and it is not able to resolve my classes anymore. However, the static field configuration
in the UnityFactory
class still contains the configuration as was provided the first time. So the class itself hasn't changed.
The Application_Start
method is not triggered after the application pool has been recycled, so the configuration is not applied again.
If I set a breakpoint and manually apply the configuration again, it all works again.
What is happening here? Why is Unity forgetting about all my classes? And is there an event I can subscribe to which allows me to know when the pool has been recycled?
Apparantly, when the application pool is recycled, the assemblies are released, which causes Unity to be unable to find any declared classes within them.
I've managed to solve this effect by specifically loading the assemblies for Unity. This way, they remain in memory, even when the application pool is recycled.
public static void Configure(Func<IAutoRegistration,IAutoRegistration> configuration)
{
// Create new UnityContainer with auto registration
container = new UnityContainer();
var autoRegistration = container.ConfigureAutoRegistration();
// Load assemblies
var path = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");
foreach (string dll in Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories))
{
autoRegistration.LoadAssemblyFrom(dll);
}
// Apply configuration
configuration(autoRegistration).ApplyAutoRegistration();
}
And to answer my questions:
What is happening here? Why is Unity forgetting about all my classes?
When the application pool recycles, assemblies may be released from memory. When they are required again, they are re-loaded. However, as they seem to come from different files, Unity is not able to know that they are in fact actually the same assemblies as before, and thus can't find the original class definitions.
And is there an event I can subscribe to which allows me to know when the pool has been recycled?
Apparantly, there is no such thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With