Dependency injection MEF与实例创建的动态决策

Dependency injection MEF与实例创建的动态决策,dependency-injection,repository,mef,unit-of-work,Dependency Injection,Repository,Mef,Unit Of Work,这可能是一种奇怪的情况,但我有时希望在使用MEF获取导出时重用同一个实例,有时创建一个新实例 基本上,我有一个WCF服务类,它是每次调用的实例。每个实例导入一个RepositoryFactory,它也是每个服务类的新实例。我在工厂中返回一个存储库,存储库得到一个IDbContext 我希望工厂的每个实例都注入相同的IDbContext实例,但在工厂实例之间有单独的实例 因此: 这将确保从同一工厂创建的存储库共享一个工作单元 但作为MEF的新手,我不确定我将如何去做 编辑 这就是我得到的: pu

这可能是一种奇怪的情况,但我有时希望在使用MEF获取导出时重用同一个实例,有时创建一个新实例

基本上,我有一个WCF服务类,它是每次调用的实例。每个实例导入一个RepositoryFactory,它也是每个服务类的新实例。我在工厂中返回一个存储库,存储库得到一个IDbContext

我希望工厂的每个实例都注入相同的IDbContext实例,但在工厂实例之间有单独的实例

因此:

这将确保从同一工厂创建的存储库共享一个工作单元

但作为MEF的新手,我不确定我将如何去做


编辑

这就是我得到的:

public class RepositoryFactory
{
    private readonly CompositionContainer _container;

    [Import(RequiredCreationPolicy=CreationPolicy.NonShared)]
    private readonly IDbContext _context;

    public IRepository<T> CreateRepository<T>() where T : class, IEntity
    {
        //Somehow add the _context instance into the Repository import

        return _container.GetExportedValue<EntityRepository<T>>();
    }
}
公共类存储工厂
{
私有只读合成容器_容器;
[导入(RequiredCreationPolicy=CreationPolicy.NonShared)]
私有只读IDbContext _context;
公共IRepository CreateRepository(),其中T:class,icity
{
//以某种方式将_上下文实例添加到存储库导入中
返回_container.GetExportedValue();
}
}
然后

public class EntityRepository<T> : IRepository<T> where T : class, IEntity
{
    // Perhaps a contract name might help!!
    [Import(RequiredCreationPolicy=CreationPolicy.Shared)]
    protected readonly IDbContext _context;
public class EntityRepository:i位置,其中T:class,entity
{
//也许一个合同名称会有所帮助!!
[导入(RequiredCreationPolicy=CreationPolicy.Shared)]
受保护的只读IDbContext\u上下文;

使用MEF无法做到这一点;无论您做什么,MEF容器都不能正确地作为您的工作单元管理器,它只是不适合于此

您应该尝试显式地为DAL使用的工作单元基础结构编写代码。您的存储库应该显式地要求工作单元管理器提供当前工作单元以及相应的上下文


看看NCommon中的代码;您可以重构工作单元功能以满足您的需要。

使用MEF无法实现这一点;无论您做什么,MEF容器都不能正确地作为您的工作单元管理器,它不是为此而设计的

您应该尝试显式地为DAL使用的工作单元基础结构编写代码。您的存储库应该显式地要求工作单元管理器提供当前工作单元以及相应的上下文


看看NCommon中的代码;您可以重构工作单元特性以满足您的需要。

好的,这里有一个解决方案,我提出了,但还没有尝试过。它有点简单,实际上可以解决MEF问题,但并没有真正破坏它,至少在我的情况下不是这样

将以下方法添加到IRepository类:

void SetContext(IDbContext context);
或者更好

IDbContext context { set; }
在工厂里:

public class RepositoryFactory
{
    private readonly CompositionContainer _container;

    [Import(RequiredCreationPolicy=CreationPolicy.NonShared)]
    private readonly IDbContext _context;

    public IRepository<T> CreateRepository<T>() where T : class, IEntity
    {
        IRepository<T> repo = _container.GetExportedValue<EntityRepository<T>>();
        repo.context = _context;

        return repo;
    }
}
公共类存储工厂
{
私有只读合成容器_容器;
[导入(RequiredCreationPolicy=CreationPolicy.NonShared)]
私有只读IDbContext _context;
公共IRepository CreateRepository(),其中T:class,icity
{
IRepository repo=_container.GetExportedValue();
repo.context=\u context;
回购回报;
}
}
其余的应该不言自明:

public  class   EntityRepository<T> :   IRepository<T>  where   T   :   class,  IEntity
{
    protected   IDbContext  _context;

    IDbContext  context
    {
        set {   _context    =   value;  }
    }

    public  virtual IQueryable<T>   GetQuery()
    {
        return  _context.Set<T>();
    }

    public  virtual T   GetById(Guid    id)
    {
        return  _context.Set<T>().Find(id);
    }

    public  virtual void    SaveOrUpdate(T  entity)
    {
        if  (_context.Set<T>().Find(entity.Id)  ==  null)
        {
            _context.Set<T>().Add(entity);
        }

        _context.SaveChanges();
    }

    public  virtual void    Delete(T    entity)
    {
        _context.Set<T>().Remove(entity);

        _context.SaveChanges();
    }
}
public class EntityRepository:i位置,其中T:class,entity
{
受保护的IDbContext _context;
IDbContext上下文
{
设置{u context=value;}
}
公共虚拟IQueryable GetQuery()
{
返回_context.Set();
}
公共虚拟T GetById(Guid id)
{
返回_context.Set().Find(id);
}
公共虚拟无效保存或更新(T实体)
{
if(_context.Set().Find(entity.Id)==null)
{
_context.Set().Add(实体);
}
_SaveChanges();
}
公共虚拟作废删除(T实体)
{
_context.Set().Remove(实体);
_SaveChanges();
}
}

如果您以与我相同的方式使用它,我看不出此实现有任何问题。工厂负责创建类,以便负责设置上下文。CreationPolicy应确保每个工厂都获得自己的DbContext实例,然后将其降级到其存储库,以便它们共享上下文。

好的,我想出了一个解决方案,但没有尝试过。它有点简单,实际上可以解决MEF问题,但并没有真正破坏它,至少在我的情况下不是这样

将以下方法添加到IRepository类:

void SetContext(IDbContext context);
或者更好

IDbContext context { set; }
在工厂里:

public class RepositoryFactory
{
    private readonly CompositionContainer _container;

    [Import(RequiredCreationPolicy=CreationPolicy.NonShared)]
    private readonly IDbContext _context;

    public IRepository<T> CreateRepository<T>() where T : class, IEntity
    {
        IRepository<T> repo = _container.GetExportedValue<EntityRepository<T>>();
        repo.context = _context;

        return repo;
    }
}
公共类存储工厂
{
私有只读合成容器_容器;
[导入(RequiredCreationPolicy=CreationPolicy.NonShared)]
私有只读IDbContext _context;
公共IRepository CreateRepository(),其中T:class,icity
{
IRepository repo=_container.GetExportedValue();
repo.context=\u context;
回购回报;
}
}
其余的应该不言自明:

public  class   EntityRepository<T> :   IRepository<T>  where   T   :   class,  IEntity
{
    protected   IDbContext  _context;

    IDbContext  context
    {
        set {   _context    =   value;  }
    }

    public  virtual IQueryable<T>   GetQuery()
    {
        return  _context.Set<T>();
    }

    public  virtual T   GetById(Guid    id)
    {
        return  _context.Set<T>().Find(id);
    }

    public  virtual void    SaveOrUpdate(T  entity)
    {
        if  (_context.Set<T>().Find(entity.Id)  ==  null)
        {
            _context.Set<T>().Add(entity);
        }

        _context.SaveChanges();
    }

    public  virtual void    Delete(T    entity)
    {
        _context.Set<T>().Remove(entity);

        _context.SaveChanges();
    }
}
public class EntityRepository:i位置,其中T:class,entity
{
受保护的IDbContext _context;
IDbContext上下文
{
设置{u context=value;}
}
公共虚拟IQueryable GetQuery()
{
返回_context.Set();
}
公共虚拟T GetById(Guid id)
{
返回_context.Set().Find(id);
}
公共虚拟无效保存或更新(T实体)
{
if(_context.Set().Find(entity.Id)==null)
{
_context.Set().Add(实体);
}
_SaveChanges();
}
公共虚拟作废删除(T实体)
{
_context.Set().Remove(实体);
_SaveChanges();
}
}
如果您以与我相同的方式使用它,我看不出此实现有任何问题。工厂负责创建类,以便负责设置上下文。CreationPolicy sho