2017-08-02 44 views
1

我有asp.net mvc应用程序,并且使用Unity作为IoC容器。 UnityWebActivator类具有PreApplicationStartMethod,它将所有类型注册到Unity容器。统一错误:应用程序初始化后无法注册模块

我想注册一个类的属性值来自数据库的单例实例。

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Web.App_Start.UnityWebActivator), "Start")] 
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(Web.App_Start.UnityWebActivator), "Shutdown")] 
namespace Web.App_Start 
{ 

    public static class UnityWebActivator 
    { 

     public static void Start() 
     { 
      var container = UnityConfig.GetConfiguredContainer(); 

      FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First()); 
      FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container)); 

      DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 

      Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule)); 

      // Web API 
      //GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container); 
     } 
    } 
} 

和UnityConfig.cs我注册的所有类型

public class UnityConfig 
{ 
    #region Unity Container 
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => 
    { 
     var container = new UnityContainer(); 
     RegisterTypes(container); 
     return container; 
    }); 

    public static IUnityContainer GetConfiguredContainer() 
    { 
     return container.Value; 
    } 

    public static void RegisterTypes(IUnityContainer container) 
    {     
     container.RegisterType<DbContext, MyEntities>(new PerRequestLifetimeManager(), new InjectionFactory(x => new MyEntities()));     

     //register singleton 
     container.RegisterInstance<ApplicationSettings>(LoadApplicationSettings(container), new ContainerControlledLifetimeManager()); 
    } 

    private static ApplicationSettings LoadApplicationSettings(IUnityContainer container) 
    { 
     var appSettings = new ApplicationSettings(); 
     using (var dbContext = new MyEntities()) 
     { 
      var settings = dbContext.Settings.ToList();    
      // populate appsettings from settings    
     } 
    } 
} 

上述LoadApplicationSettings方法需要从数据库中获取数据,并创建的applicationSettings类的实例。

然而LoadApplicationSettings被援引为PreApplicationStartMethod这是之前application_start方法,因为的DbContext尚未映射,我得到错误

InvalidOperationException: Unable to determine application context. The ASP.NET application path could not be resolved.

and: 

InvalidOperationException: This method cannot be called during the application's pre-start initialization stage.

所以按照建议here我做了两两件事:

1>移除[assembly:WebActivator.PreApplicationStartMethod]
2>在全局asax的Application_Start()事件中添加对UnityWebActivator.Start()方法的调用。

但是做登记UnityPerRequestHttpModule

public static void Start() 
    { 
     // removed code for brevity 

     // get error at line below 
     Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule)); 

     //removed code for brevity 
    } 

"Cannot register a module after the application has been initialized."}

回答

0

您可以使用InjectionConstructor注册ApplicationSettings所以会导致另一个错误。这将推迟创建(以及从数据库加载设置),直到第一次从容器解析为止。推测这应该在应用程序完成引导之后。

这里是新注册:

//register singleton 
container.RegisterType<ApplicationSettings>(
    new ContainerControlledLifetimeManager(), 
    new InjectionFactory(c => LoadApplicationSettings(c))); 
相关问题