C# 用单例实现依赖注入
我将WPF与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) {
实体框架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自身发布到容器将为您完成所有工作。