C# 用单例实现依赖注入

C# 用单例实现依赖注入,c#,wpf,dependency-injection,inversion-of-control,C#,Wpf,Dependency Injection,Inversion Of Control,我将WPF与实体框架6(DB优先)、Caliburn.Micro和MEF一起使用 我正试图在我的项目中实现IoC。我是IoC的绝对初学者,不幸的是,我找不到太多的例子将MEF与存储库模式一起使用 因此,我有一些存储库,我创建了这样的通用工作单元: class GenericUoW : IUoW, IDisposable { protected readonly DbContext _ctx; public GenericUoW(DbContext context) {

我将WPF与
实体框架6
(DB优先)、
Caliburn.Micro
MEF
一起使用

我正试图在我的项目中实现
IoC
。我是
IoC
的绝对初学者,不幸的是,我找不到太多的例子将
MEF
存储库模式一起使用

因此,我有一些存储库,我创建了这样的通用工作单元:

class GenericUoW : IUoW, IDisposable
{
    protected readonly DbContext _ctx;

    public GenericUoW(DbContext context)
    {
        _ctx = context;
    }

    public void Complete()
    {
        _ctx.SaveChanges();
    }

    public void Dispose()
    {
        _ctx.Dispose();
    }
}
class InvoiceUoW : GenericUoW, IInvoiceUoW
{
    public InvoiceUoW(DbContext _ctx) : base(_ctx)
    {
        salesrepo = new SaleRepository(_ctx);
        itemsrepo = new ItemRepository(_ctx);
        materialrepo = new MaterialRepository(_ctx);
        raterepo = new RateRepository(_ctx);
        clientrepo = new ClientRepository(_ctx);
        taxrepo = new TaxRepository(_ctx);
        stockhistoryrepo = new StockHistoryRepository(_ctx);
        proformarepo = new ProformaRepository(_ctx);
    }

    public ISaleRepository salesrepo { get; private set; }
    public IItemRepository itemsrepo { get; private set; }
    public IMaterialRepository materialrepo { get; private set; }
    public IRateRepository raterepo { get; private set; }
    public IClientRepository clientrepo { get; private set; }
    public ITaxRepository taxrepo { get; private set; }
    public IStockHistoryRepository stockhistoryrepo { get; private set; }
    public IProformaRepository proformarepo { get; private set; }
}
[Export(typeof(InvoiceViewModel))]    
class InvoiceViewModel : PropertyChangedBase
{

    #region ctor
    [ImportingConstructor]
    public InvoiceViewModel(IInvoiceUoW invoiceUoW)
    {
        _uow = invoiceUoW;
        Clients = new BindableCollection<Client>(_uow.clientrepo.FetchAll());
    }

    #endregion

    private readonly IInvoiceUoW _uow;

    //other properties and methods
}
我的实际工作单元类是这样实现的:

class GenericUoW : IUoW, IDisposable
{
    protected readonly DbContext _ctx;

    public GenericUoW(DbContext context)
    {
        _ctx = context;
    }

    public void Complete()
    {
        _ctx.SaveChanges();
    }

    public void Dispose()
    {
        _ctx.Dispose();
    }
}
class InvoiceUoW : GenericUoW, IInvoiceUoW
{
    public InvoiceUoW(DbContext _ctx) : base(_ctx)
    {
        salesrepo = new SaleRepository(_ctx);
        itemsrepo = new ItemRepository(_ctx);
        materialrepo = new MaterialRepository(_ctx);
        raterepo = new RateRepository(_ctx);
        clientrepo = new ClientRepository(_ctx);
        taxrepo = new TaxRepository(_ctx);
        stockhistoryrepo = new StockHistoryRepository(_ctx);
        proformarepo = new ProformaRepository(_ctx);
    }

    public ISaleRepository salesrepo { get; private set; }
    public IItemRepository itemsrepo { get; private set; }
    public IMaterialRepository materialrepo { get; private set; }
    public IRateRepository raterepo { get; private set; }
    public IClientRepository clientrepo { get; private set; }
    public ITaxRepository taxrepo { get; private set; }
    public IStockHistoryRepository stockhistoryrepo { get; private set; }
    public IProformaRepository proformarepo { get; private set; }
}
[Export(typeof(InvoiceViewModel))]    
class InvoiceViewModel : PropertyChangedBase
{

    #region ctor
    [ImportingConstructor]
    public InvoiceViewModel(IInvoiceUoW invoiceUoW)
    {
        _uow = invoiceUoW;
        Clients = new BindableCollection<Client>(_uow.clientrepo.FetchAll());
    }

    #endregion

    private readonly IInvoiceUoW _uow;

    //other properties and methods
}
现在,在我的
ViewModel
中,我正在做这样的事情:

class GenericUoW : IUoW, IDisposable
{
    protected readonly DbContext _ctx;

    public GenericUoW(DbContext context)
    {
        _ctx = context;
    }

    public void Complete()
    {
        _ctx.SaveChanges();
    }

    public void Dispose()
    {
        _ctx.Dispose();
    }
}
class InvoiceUoW : GenericUoW, IInvoiceUoW
{
    public InvoiceUoW(DbContext _ctx) : base(_ctx)
    {
        salesrepo = new SaleRepository(_ctx);
        itemsrepo = new ItemRepository(_ctx);
        materialrepo = new MaterialRepository(_ctx);
        raterepo = new RateRepository(_ctx);
        clientrepo = new ClientRepository(_ctx);
        taxrepo = new TaxRepository(_ctx);
        stockhistoryrepo = new StockHistoryRepository(_ctx);
        proformarepo = new ProformaRepository(_ctx);
    }

    public ISaleRepository salesrepo { get; private set; }
    public IItemRepository itemsrepo { get; private set; }
    public IMaterialRepository materialrepo { get; private set; }
    public IRateRepository raterepo { get; private set; }
    public IClientRepository clientrepo { get; private set; }
    public ITaxRepository taxrepo { get; private set; }
    public IStockHistoryRepository stockhistoryrepo { get; private set; }
    public IProformaRepository proformarepo { get; private set; }
}
[Export(typeof(InvoiceViewModel))]    
class InvoiceViewModel : PropertyChangedBase
{

    #region ctor
    [ImportingConstructor]
    public InvoiceViewModel(IInvoiceUoW invoiceUoW)
    {
        _uow = invoiceUoW;
        Clients = new BindableCollection<Client>(_uow.clientrepo.FetchAll());
    }

    #endregion

    private readonly IInvoiceUoW _uow;

    //other properties and methods
}
[导出(typeof(InvoiceViewModel))]
类InvoiceViewModel:PropertyChangedBase
{
#区域导体
[导入构造函数]
公共发票视图模型(IInvoiceUoW发票)
{
_uow=发票uow;
Clients=newbindablecolection(_uow.clientrepo.FetchAll());
}
#端区
私有只读IInvoiceUoW;
//其他性质和方法
}

我的问题与
InvoiceUoW
中的
IoC/DI
有关。如何在该类中实现
构造函数注入
?因为该类中的每个存储库都必须使用相同的
DataContext
进行实例化。如何使
DataContext
成为单例?请注意,我有几个
工作单元
类,每个类对应一个
viewmodel
注册要解析的
DbContext
实例,并像单个实例一样工作:

var container = new CompositionContainer(); //Get it from where it belongs
var dbContext = container.GetExportedValue<DbContext>();
container.ComposeExportedValue<DbContext>(dbContext);

注册要解析的
DbContext
实例,并像单例一样操作:

var container = new CompositionContainer(); //Get it from where it belongs
var dbContext = container.GetExportedValue<DbContext>();
container.ComposeExportedValue<DbContext>(dbContext);

永远不要将EF DbContext用作单例。InvoiceUoW的每个实例都应该接收自己的上下文实例。顺便说一句,EF上下文已经遵循UoW模式,而每个数据库集都遵循通用存储库模式,因此围绕它的包装实际上是毫无意义的。
InvoiceUoW的每个实例都应该接收自己的上下文实例。
我明白了。但是如何才能使
UoW
中的所有存储库都使用相同的
DbContext
进行实例化呢?当我尝试使用
MEF
执行此操作时,它会执行与此等效的操作:
salerepo=newsalerepository(newdbcontext());itemsrepo=newitemrepository(newdbcontext());materialrepo=newmaterialrepository(newdbcontext())但是您的代码显示您手动实例化了“存储库”,并在那里传递了相同的上下文:
salerepo=newsalerepository(_ctx)
这就是我现在保存它的方式,因为我无法使用
MEF
正确地执行它。为什么您希望它们都使用相同的上下文实例?您不应该将EF DbContext用作singleton。InvoiceUoW的每个实例都应该接收自己的上下文实例。顺便说一句,EF上下文已经遵循UoW模式,而每个数据库集都遵循通用存储库模式,因此围绕它的包装实际上是毫无意义的。
InvoiceUoW的每个实例都应该接收自己的上下文实例。
我明白了。但是如何才能使
UoW
中的所有存储库都使用相同的
DbContext
进行实例化呢?当我尝试使用
MEF
执行此操作时,它会执行与此等效的操作:
salerepo=newsalerepository(newdbcontext());itemsrepo=newitemrepository(newdbcontext());materialrepo=newmaterialrepository(newdbcontext())但是您的代码显示您手动实例化了“存储库”,并在那里传递了相同的上下文:
salerepo=newsalerepository(_ctx)
这就是我现在保存它的方式,因为我无法使用
MEF
正确地执行它。为什么您希望它们都使用相同的上下文实例?我如何在
UnitOfWork
中使用
[ImportingConstructor]
?只要其参数熟悉容器,将UoW自身发布到容器将为您完成所有工作。如何在
工作单元中使用
[ImportingConstructor]
?只要其参数熟悉容器,将UoW自身发布到容器将为您完成所有工作。