2

想知道是否有人在使用 Castle Windsor 3.0 时遇到过这种奇怪的行为?我已经为 DbContext 设置了容器配置,使其具有 PerWebRequest 的生活方式,但 Castle 不会在 WebRequest 之后处理组件。它将组件跨 Web 请求保留在 Container 中,就好像它是 Singleton 一样。

显而易见的问题是当 DbContext 中存在数据库错误时,它会阻止所有未来的 CRUD 操作,直到 IIS 重新启动(即手动销毁 DbContext)!正如我们所知,这是不可接受的。

如果 DbContext 被 PerWebRequest 回收,那么当页面重新加载时,其他 CRUD 操作将成功执行,因为我们现在有了一个新的 DbContext。

我的配置如下:

    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