【发布时间】:2011-04-20 06:57:38
【问题描述】:
我不知道如何配置正确的 Windsor 容器以与 Windows 应用程序中的存储库一起使用。 我有通用存储库实现Repository,其中T是实体类型,它有一个依赖IDatacontextProvider,它为其提供数据上下文:
public class Repository<T> : IRepository<T> where T : class
{
protected DataContext DataContext;
public Repository(IDataContextProvider dataContextProvider) {
DataContext = dataContextProvider.DataContext;
}
....
}
对于简单的事情,以下配置一切正常:
container.Register(
Component.For<IDataContextProvider>()
.ImplementedBy<DataContextProvider>()
.Lifestyle.Transient,
Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>))
.Lifestyle.Transient, ....
当我尝试加入来自多个存储库的不同实体时,只要每个存储库实例具有不同的数据上下文实例,就会出现问题。
例如我有简单的服务:
public class SimpleService : ISimpleService {
public SimpleService(IRepository<Order>, IRepository<OrderLine>) {
....
}
}
我可以将 IDataContextProvider 设为 Singleton,但我认为这会带来更大的问题。
我可以将 IDataContextProvider 传递给 SimpleService,并尝试在那里解析存储库实例,但这需要额外的代码来使服务易于测试,并且需要额外的依赖项。
可能有人对如何解决这个问题有更好的想法?
更新: 根据建议,我创建了存储库工厂(它与答案中提出的有点不同,它不直接依赖于数据上下文,但想法非常相同):
public interface IRepositoryFactory
{
IRepository<T> GetRepository<T>() where T:class;
}
public class RepositoryFactory : IRepositoryFactory
{
private readonly IDataContextProvider dataContextProvider;
public RepositoryFactory(IDataContextProvider dataContextProvider)
{
this.dataContextProvider = dataContextProvider;
}
public IRepository<T> GetRepository<T>() where T : class
{
return new Repository<T>(dataContextProvider);
}
}
【问题讨论】:
-
为什么单例会导致“更大”的问题?对于只有一个线程的 Windows 应用程序,这应该是最好的选择..
-
好吧,因为 DataContext 并不意味着长寿(它没有缓存清除、多次提交的更改分离等 - 它假设您将释放它并尽快创建新实例可能),对此有很多讨论(例如:stackoverflow.com/questions/226127/…)。此外,还有多个用户,并且在很多地方都使用了线程。
-
好的,我明白了。对Entity Framework不太熟悉,自己用NHibernate。为什么没有一个 RepositoryFactory,它需要一个 IDataContextProvider。您的用户类可以将 IRepositoryFactory 作为依赖项,并从那里获取他们需要的存储库,并且从 RepositoryFactory 的同一实例创建的所有存储库将共享相同的 DataContext。
-
非常有趣的想法,我会尝试看看它在代码中的样子。
-
我添加了一个可能的解决方案的答案。
标签: c# winforms castle-windsor ioc-container