Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windsor的通用存储库生存期配置_C#_Winforms_Castle Windsor_Ioc Container - Fatal编程技术网

C# Windsor的通用存储库生存期配置

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

我不知道如何配置合适的Windsor容器以用于Windows应用程序中的存储库。 我有一个通用存储库实现存储库,其中T是实体类型,它有一个依赖项IDatacontextProvider,它为它提供datacontext:

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
    ,可能应该考虑将其显式提供为方法参数,而不是注入依赖项
  • @Can的答案也是一个可能的解决方案,我自己也用过一次

  • 您的问题在于生活方式的配置。我也有同样的问题。您必须使用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) {
             ....
         }
    }