想知道是否有人在使用 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; }
}
任何帮助/建议将不胜感激。
谢谢。