[英]How can I use StructureMap DI for this situation?
I have a class called unitofwork
which implements IUnitOfWork
我有一个叫做
unitofwork
的类,它实现了IUnitOfWork
public class UnitOfWork : IUnitOfWork
{
private readonly IDbContext _context;
private bool _disposed;
private Hashtable _repositories;
public UnitOfWork(IDbContext dbContext)
{
_context = dbContext;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Save()
{
_context.SaveChanges();
}
public virtual void Dispose(bool disposing)
{
if (!_disposed)
if (disposing)
_context.Dispose();
_disposed = true;
}
public IRepository<T> Repository<T>() where T : class
{
if (_repositories == null)
_repositories = new Hashtable();
var type = typeof(T).Name;
if (!_repositories.ContainsKey(type))
{
var repositoryType = typeof(BaseRepository<>);
var repositoryInstance =
Activator.CreateInstance(repositoryType
.MakeGenericType(typeof(T)), _context);
_repositories.Add(type, repositoryInstance);
}
return (IRepository<T>)_repositories[type];
}
}
And two classes which implement IDbContext
还有两个实现
IDbContext
类
public class SecurityContext:IDbContext{}
public class HrContext:IDbContext{}
I also have two controllers, which depend on IUnitOfWork
我也有两个控制器,它们依赖于
IUnitOfWork
public LoginController(IUnitOfWork _securityContextUow)
{
// Here the injected unitofwork
// object must have SecurityContext ,as its dependent instance
}
public SalaryController(IUnitOfWork _hrContextUow)
{
// Here the injected unitofwork
// object must have HrContext,as its dependent instance
}
How can I configure StructureMap to achieve this? 如何配置StructureMap来实现此目的? In my current configuration, I can only configure one instance for
IDbContext
在当前配置中,我只能为
IDbContext
配置一个实例
x.For<IDbContext>().Use<SecurityContext>();
Summary: I want to inject an instance of unitofwork
with SecurityContext
to LoginController
and inject an instance of unitofwork
with HrContext
to SalaryController
. 摘要:我要注入的一个实例
unitofwork
用SecurityContext
到LoginController
,注入的一个实例unitofwork
与HrContext
到SalaryController
。 To do that what are the configuration /changes in constructor required ? 为此,构造函数需要进行哪些配置/更改?
If the UnitOfWork
logic is common then the easiest solution is to make UnitOfWork
generic 如果
UnitOfWork
逻辑是通用的,那么最简单的解决方案是使UnitOfWork
通用
interface IUnitOfWork<TContext> where TContext: IDbContext { }
public class UnitOfWork<TContext> : IUnitOfWork<TContext>
where TContext : IDbContext
{
private readonly TContext context;
public UnitOfWork(TContext context)
{
this.context = context;
}
}
Then, using the following syntax to register the UnitOfWork
and the IDbContext
's 然后,使用以下语法注册
UnitOfWork
和IDbContext
的
ObjectFactory.Configure(x =>
{
x.For(typeof(IUnitOfWork<>)).Use(typeof(UnitOfWork<>));
});
You can control which IDbContext
is injected into the UnitOfWork
您可以控制将哪个
IDbContext
注入到UnitOfWork
public LoginController(IUnitOfWork<SecurityContext> securityContextUow) { }
public SalaryController(IUnitOfWork<HrContext> hrContextUow) { }
Here's a quick unit test to prove it works as expected 这是一个快速的单元测试,可以证明它能按预期运行
public class TestUnitOfWork<TContext> : IUnitOfWork<TContext>
where TContext : IDbContext
{
public TContext context { get; set; }
public TestUnitOfWork(TContext context)
{
this.context = context;
}
}
[Test]
public void GetCorrectUnitOfWork()
{
ObjectFactory.Configure(x =>
{
x.For(typeof(IUnitOfWork<>)).Use(typeof(TestUnitOfWork<>));
});
//ObjectFactory.AssertConfigurationIsValid();
var securityContextUow = ObjectFactory
.GetInstance<IUnitOfWork<SecurityContext>>();
var hrContextUow = ObjectFactory
.GetInstance<IUnitOfWork<HrContext>>();
Assert
.That((securityContextUow as TestUnitOfWork<SecurityContext>).context,
Is.InstanceOf<SecurityContext>());
Assert
.That((hrContextUow as TestUnitOfWork<HrContext>).context,
Is.InstanceOf<HrContext>());
}
One approach would be to separate everything out a little more so that you have extra interfaces for each unit of work and related classes. 一种方法是将所有内容分开一些,以便为每个工作单元和相关类提供额外的接口。 Something like this:
像这样:
public interface ISecurityContext : IDbContext {}
public interface IHrContext : IDbContext {}
public interface ISecurityUnitOfWork : IUnitOfWork {}
public interface IHrUnitOfWork : IUnitOfWork {}
Then your unit of work classes take in the relevant context: 然后,您的工作单元类别将包含以下相关上下文:
public class SecurityUnitOfWork : UnitOfWork,ISecurityUnitOfWork
{
public SecurityUnitOfWork(ISecurityContext context)
: base(context)
{
// This change
}
} }
And your controller can take in the relevant unit of work: 您的控制器可以接管相关的工作单元:
public LoginController(ISecurityUnitOfWork securityUnitOfWork)
{
}
You still have the base IUnitOfWork
and IDbContext
interfaces but now have a logically related grouping for each set of operations. 您仍然具有基本的
IUnitOfWork
和IDbContext
接口,但是现在对每组操作都有一个逻辑相关的分组。 It's a bit more heavyweight than the approach you're looking for but it should make your DI resolution simpler to understand. 它比您正在寻找的方法要重一些,但是它应该使您的DI分辨率更易于理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.