2

Castle Windsor 3.0 でこの奇妙な動作に遭遇した人はいますか? DbContext のコンテナ構成を PerWebRequest のライフスタイルに設定しましたが、Castle は WebRequest の後にコンポーネントを破棄しません。シングルトンであるかのように、Web リクエスト間でコンポーネントをコンテナ内に保持します。

これを明らかにする問題は、DbContext にデータベース エラーがある場合です。これにより、IIS が再起動されるまで (つまり、手動で DbContext を破棄するまで)、以降のすべての CRUD 操作が実行されなくなります。私たちが知っているように、これは受け入れられません。

DbContext が PerWebRequest でリサイクルされる場合、ページがリロードされると、新しい DbContext があるため、他の CRUD 操作が正常に実行されます。

私の設定は以下の通りです:

    private static IWindsorContainer InitializeWindsor()
    {
        var container = new WindsorContainer();

        // Add Factory facility
        container.AddFacility<TypedFactoryFacility>();

        // Add AOP facility
        container.AddFacility<AdditionalFunctionalityFacility>();

        // Register all controllers from this assembly
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            container.Register(
                Classes.FromAssembly(assembly).BasedOn<Controller>().Configure(c => c.LifestyleTransient())
                );
        }

        // Adding logging facility. This has to happen after Controller registration, otherwise it bombs out
        container.AddFacility<LoggingFacility>(f => f.UseLog4Net());

        // Register HTTP Handlers
        container.Register(Component.For<HttpRequestBase>().LifeStyle.PerWebRequest
                   .UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request)));
        container.Register(Component.For<HttpContextBase>().LifeStyle.PerWebRequest
                               .UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));

        // Register components
        container.Register(

            // Factories - singletons
            Component.For<IServiceFactory>().LifeStyle.PerWebRequest.LifeStyle.Is(LifestyleType.Thread).AsFactory(),
            Component.For<IDataFactory>().LifeStyle.PerWebRequest.LifeStyle.Is(LifestyleType.Thread).AsFactory(),

            // Services
            Component.For<IRegionService>().ImplementedBy<RegionService>().LifeStyle.PerWebRequest,

            // Data Managers
            Component.For<IRegionManager>().ImplementedBy<RegionManager>().LifeStyle.PerWebRequest,

            // Data Contexts
            Component.For<DbContext>().ImplementedBy<MyDataContext>().LifeStyle.PerWebRequest.LifeStyle.Is(LifestyleType.Thread)
            );

        return container;
    }

私の DbContext クラスは以下のとおりです。

public partial class MyDataContext : DbContext
{
    static MyDataContext()
    { 
        Database.SetInitializer<MyDataContext>(null);
    }

    public MyDataContext() : base("name=MyDataContext")
    {
    }

    public MyDataContext(string nameOrConnectionString) : base(nameOrConnectionString)
    {   
    }

    public MyDataContext(string nameOrConnectionString, DbCompiledModel model) : base(nameOrConnectionString, model)
    {
    }

    public MyDataContext(DbConnection existingConnection, bool contextOwnsConnection) : base(existingConnection, contextOwnsConnection)
    {
    }

    public MyDataContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection) : base(existingConnection, model, contextOwnsConnection)
    {
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
        modelBuilder.Configurations.Add(new Region_Mapping());
    }

    public DbSet<Region> Regions { get; set; }

}

任意のヘルプ/提案をいただければ幸いです。

ありがとう。

4

0 に答える 0