2017-08-02 10 views
1

私はasp.net mvcアプリケーションを持っていて、UnityをIoCコンテナとして使用しています。 UnityWebActivatorクラスはUnityコンテナですべてのタイプを登録するPreApplicationStartMethodを持っています。Unity Error:アプリケーションが初期化された後でモジュールを登録できません。

プロパティ値がデータベースから来ているクラスのシングルトンインスタンスを登録したいとします。

[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); 
     } 
    } 
} 

と私は上記のLoadApplicationSettings方法は、データベースからデータを取得し、ApplicationSettingsクラスのインスタンスを作成するために必要なすべての種類の

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    
     } 
    } 
} 

を登録UnityConfig.cs。

しかしLoadApplicationSettingsapplication_startメソッドの前にあるPreApplicationStartMethodとして呼び出されると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.

だから私は2つのことでした提案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))); 
関連する問題