使用Windsor进行通用存储库生存期配置

时间:2011-04-20 06:57:38

标签: c# winforms castle-windsor ioc-container

我没有想法如何配置正确的Windsor容器以与Windows应用程序中的存储库一起使用。 我有通用的存储库实现Repository,其中T是实体类型,它有一个依赖IDatacontextProvider,它为它提供datacontext:

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,并尝试在那里解析存储库实例,但这需要额外的代码才能使服务易于测试,并且需要额外的依赖性。 可能有人有更好的想法如何解决这个问题?

更新: 以下建议,我已经创建了存储库工厂(它与回答中提出的有点不同,它没有直接依赖于datacontext,但想法非常相似):

 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);
    }
}

3 个答案:

答案 0 :(得分:2)

如果在其间有另一层,比如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) {
         ....
     }
}

答案 1 :(得分:1)

IDatacontextProvider听起来像工厂界面,这些通常在依赖注入中定义为单例。我看到解决方案的几种可能途径:

  1. 我不知道您的申请的详细信息,但也许您可以IDatacontextProvider编写自己的生活方式经理(因为您既不会说单身也不适合您。)
  2. 如果您想确保在存储库之间传递相同的IDatacontextProvider,也许您应该考虑明确地将其作为方法参数提供,而不是注入依赖项。
  3. @Can的答案也是一个可能的解决方案,我自己曾经使用过那个。

答案 2 :(得分:0)

你的问题在于生活方式的配置。我有同样的问题。您必须使用PerWebRequest生活方式配置存储库。这给了我一个很好的性能提升,并将我的错误从几十减少到零。

在我的博客上,您可以先找到一个简单的http://marcofranssen.nl依赖注入示例,并结合mvc3和EF代码。