C# Windsor的通用存储库生存期配置
我不知道如何配置合适的Windsor容器以用于Windows应用程序中的存储库。 我有一个通用存储库实现存储库,其中T是实体类型,它有一个依赖项IDatacontextProvider,它为它提供datacontext:C# Windsor的通用存储库生存期配置,c#,winforms,castle-windsor,ioc-container,C#,Winforms,Castle Windsor,Ioc Container,我不知道如何配置合适的Windsor容器以用于Windows应用程序中的存储库。 我有一个通用存储库实现存储库,其中T是实体类型,它有一个依赖项IDatacontextProvider,它为它提供datacontext: public class Repository<T> : IRepository<T> where T : class { protected DataContext DataContext; public Repository(IDat
public class Repository<T> : IRepository<T> where T : class
{
protected DataContext DataContext;
public Repository(IDataContextProvider dataContextProvider) {
DataContext = dataContextProvider.DataContext;
}
....
}
公共类存储库:IRepository,其中T:class
{
受保护的数据上下文数据上下文;
公共存储库(IDataContextProvider dataContextProvider){
DataContext=dataContextProvider.DataContext;
}
....
}
对于简单的事情,通过以下配置,一切正常:
container.Register(
Component.For<IDataContextProvider>()
.ImplementedBy<DataContextProvider>()
.Lifestyle.Transient,
Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>))
.Lifestyle.Transient, ....
container.Register(
用于()的组件
.由()实施
.生活方式,
组件。用于(类型(IRepository))
.ImplementedBy(类型(存储库))
.生活方式。。。。
当我尝试连接多个存储库中的不同实体时,只要每个存储库实例具有不同的数据上下文实例,就会出现问题。例如,我有简单的服务:
public class SimpleService : ISimpleService {
public SimpleService(IRepository<Order>, IRepository<OrderLine>) {
....
}
}
public类SimpleService:ISimpleService{
公共SimpleService(IRepository,IRepository){
....
}
}
我可以将IDataContextProvider设置为Singleton,但我认为这会带来更大的问题。我可以将IDataContextProvider传递给SimpleService,并尝试在那里解析存储库实例,但这需要额外的代码使服务易于测试,并且需要额外的依赖项。 也许有人有更好的办法解决这个问题 更新: 按照建议,我创建了repository factory(它和答案中提出的有点不同,它不直接依赖于datacontext,但想法非常相同):
公共接口IRepositoryFactory
{
IRepository GetRepository(),其中T:class;
}
公共类存储工厂:IRepositoryFactory
{
私有只读IDataContextProvider dataContextProvider;
公共RepositoryFactory(IDataContextProvider dataContextProvider)
{
this.dataContextProvider=dataContextProvider;
}
公共IRepository GetRepository(),其中T:class
{
返回新存储库(dataContextProvider);
}
}
如果中间有另一层,例如RepositoryFactory,那该层会有一种暂时的生活方式。从该工厂创建的所有存储库都将共享同一个DataContext实例。您还需要更改存储库类,以便它们采用DataContext实例而不是DataContextProvider
public class RepositoryFactory : IRepositoryFactory
{
protected DataContext dataContext;
public RepositoryFactory(IDataContextProvider provider)
{
dataContext = dataContextProvider.DataContext;
}
public IRepository<T> GetRepository<T>()
{
return new Repository<T>(dataContext);
}
}
public class SimpleService : ISimpleService {
public SimpleService(IRepositoryFactory factory) {
....
}
}
公共类RepositoryFactory:IRepositoryFactory
{
受保护的数据上下文数据上下文;
公共存储工厂(IDataContextProvider)
{
dataContext=dataContextProvider.dataContext;
}
公共IRepository GetRepository()
{
返回新存储库(dataContext);
}
}
公共类SimpleService:ISimpleService{
公共SimpleService(IRepositoryFactory){
....
}
}
IDatacontextProvider
听起来像一个工厂接口,这些接口通常在依赖项注入中定义为单例。我看到了几种解决方案的潜在路径:
IDatacontextProvider
编写自己的生活方式管理器(因为您说singleton和transient都不适合您)IDatacontextProvider
,可能应该考虑将其显式提供为方法参数,而不是注入依赖项您的问题在于生活方式的配置。我也有同样的问题。您必须使用PerWebRequest生活方式配置存储库。这给了我很好的性能提升,并将我的错误从几十个减少到零
在我的博客上,你可以首先找到一个简单的依赖注入与mvc3和EF代码结合的例子。我在问题中提到,这是Windows应用程序,所以PerWebRequest不适用于这种情况。我在我的web应用程序中使用了相同的存储库实现,但效果很好。为什么singleton会导致“更大”的问题问题?对于只有一个线程的windows应用程序,这应该是最好的选择..因为DataContext不会长久存在(它没有缓存清除、多次提交的更改分离等功能-它假设您将尽快释放它并创建新实例),所以对此有很多讨论(例如:)。此外,还有多个用户,线程在很多地方使用。好的,我理解。不太熟悉实体框架,我自己使用NHibernate。为什么不拥有一个RepositoryFactory,它采用IDataContextProvider。您的用户类可以将IRepositoryFactory作为一个依赖项,并从那里获得他们需要的存储库和所有repo从RepositoryFactory的同一实例创建的情景将共享相同的DataContext。这是一个非常有趣的想法,我将尝试在代码中查看它的外观。我添加了一个可能的解决方案。关于自己的生活方式,它看起来也非常有趣和干净。@Giedrius,这个链接也很有趣,但我不喜欢你这样做需要对内核进行引用才能创建ContainerContext。这意味着将创建上下文的客户机类需要了解castle内核。@Can,嗯,我也不喜欢这样,但从另一方面来说,它可能有助于解决更复杂的组合问题,比如serviceA使用serviceB,两者都使用repositoryC和repositoryD,它们需要有相同的数据上下文。有人提到,我说的是windows应用程序,不是web应用程序。我知道,但你可以翻译这个考试
public class RepositoryFactory : IRepositoryFactory
{
protected DataContext dataContext;
public RepositoryFactory(IDataContextProvider provider)
{
dataContext = dataContextProvider.DataContext;
}
public IRepository<T> GetRepository<T>()
{
return new Repository<T>(dataContext);
}
}
public class SimpleService : ISimpleService {
public SimpleService(IRepositoryFactory factory) {
....
}
}