Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity configuration missing after application pool restart

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?

like image 724
René Wolferink Avatar asked Nov 04 '22 11:11

René Wolferink


1 Answers

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.

like image 159
René Wolferink Avatar answered Nov 15 '22 05:11

René Wolferink