ASP.NET API DI (Simple Injector) null reference on

2019-03-02 09:02发布

问题:

I previously posted another question, but after some observations, I have narrowed down to what it may be that's causing my problem. Basically, once the IIS Application Pool is recycled, my dependency injection (which ends up scanning for some DLLs through creating an NWatchApplication), fails. INWatchApplication is a dependency for the Web API project.

Here are the contents of the Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    var webApiContainer = new Container();
    webApiContainer.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
    RegisterTypes(webApiContainer);
    webApiContainer.RegisterWebApiControllers(GlobalConfiguration.Configuration);
    webApiContainer.Verify();

    GlobalConfiguration.Configuration.DependencyResolver =
        new SimpleInjectorWebApiDependencyResolver(webApiContainer);
}

private void RegisterTypes(Container container)
{
    var virtualPath = HostingEnvironment.ApplicationVirtualPath.Substring(1);
    string baseName = null;

    if (!string.IsNullOrEmpty(virtualPath)) {
        baseName = HostingEnvironment.SiteName + "_" + virtualPath;
    } else {
        baseName = HostingEnvironment.SiteName;
    }

    var nWatchApp = new NWatchEntityApplication(GetNWatchConfig());
    Trace.Listeners.Add(new DevOps.Diagnostics.DevOpsLogTraceListener(baseName));
    container.RegisterSingleton<INWatchApplication>(nWatchApp);
    container.Register<NWatchDbContext>(() => nWatchApp.GetDbContext(), Lifestyle.Scoped);
}

private INWatchConfiguration GetNWatchConfig()
{
    Configuration rootConfig =
        System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(HostingEnvironment.ApplicationVirtualPath);
    return new NWatchSystemConfiguration(rootConfig);
}

I have read various blogs and posts talking about how dynamically loaded DLLs seem to be a problem, because when IIS recycles the pools, they aren't copied to the AppDomain. (I could be totally wrong here, but it is my suspicion).

How do I ensure that all DLLs that may have loaded (when the Application was first deployed to IIS) continue to be available to the Application even after a recycle?

回答1:

var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();

Put inside of the Global.asax Application_Start() seems to have resolved the issue!