我有一个基类和一些派生类。基类包含需要注入的属性。如何配置Unity来构建我的对象?
public class BaseService<T> where T : class
{
public T Entity { get; private set; }
[Dependency]
public IUnitOfWork UnitOfWork { get; private set; }
public BaseService(T obj)
{
this.Entity = obj;
}
}
public class ContactService : BaseService<Contact>
{
public ContactService(Contact obj) : base(obj)
{
}
public bool IsValid()
{
bool result = false;
// ...
return result;
}
public void AddContact()
{
if (!IsValid()) { throw new InvalidEntityException<Contact>(); }
try
{
this.UnitOfWork.BeginTransaction();
this.UnitOfWork.Add<Contact>(this.Entity);
this.UnitOfWork.CommitTransaction();
}
catch
{
this.UnitOfWork.RollbackTransaction();
}
}
}
我如何首先注册这个,然后如何解决ContactService,因为它有一个带有无法注入参数的构造函数?我应该为此使用Unity吗?
答案 0 :(得分:2)
您可以使用UnitiContainer.BuildUp注入现有对象的依赖项。如果构造函数参数具有一组预定义的小值,则可以使用InjectionConstructor类在注册期间指定参数的值。否则,请使用Unity注册工厂类,并使用它来创建服务。
public class ContactServiceFactory
{
IUnitOfWork UnitOfWork { get; private set; }
public ContractServiceFactory(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
}
public ContactService Create(Contact obj)
{
return new ContractService(obj, unitOfWork);
}
}
答案 1 :(得分:1)
我试图通过构造这样的事情来避免这种情况:
public class ContactService : IContactService
{
private readonly IContactRepository repository;
private readonly IValidator<Contact> validator;
private readonly IUnitOfWork unitOfWork;
public ContactService(
IContactRepository repository,
IValidator<Contact> validator,
IUnitOfWork unitOfWork)
{
this.repository = repository;
this.validator = validator;
this.unitOfWork = unitOfWork;
}
public void Add(Contact contact)
{
if (!validator.IsValid(contact)) throw new ArgumentException();
try
{
unitOfWork.Start();
repository.Save(contact);
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
}
有了这个基本模式,Unity可以使用其所有依赖关系构建您的服务,并且您不会遇到注入联系人的问题。存储库可以用作抽象,或者直接使用您最喜欢的数据访问框架,如EF,NHibernate或普通的旧Ado.Net,如果这就是你的方式。
由于try catch东西是重复的,你可以使用扩展方法压缩代码,如下所示:
public void Add(Contact contact)
{
if (!validator.IsValid(contact)) throw new ArgumentException();
unitOfWork.Execute(() => repository.Save(contact));
}
扩展方法如下所示:
public static class UnitOfWorkExtensions
{
public static void Execute(this IUnitOfWork unitOfWork, Action action)
{
try
{
unitOfWork.Start();
action.Invoke();
unitOfWork.Commit();
}
catch
{
unitOfWork.Rollback();
throw;
}
}
}
更多相关信息:http://www.agileatwork.com/refactoring-c-style/
以这种方式构建代码的一大优势是,您可以利用Unity的拦截机制并执行许多很酷的操作,例如将工作单元代码移动到方面(属性):
[UnitOfWork]
public void Add(Contact contact)
{
if (!validator.IsValid(contact)) throw new ArgumentException();
repository.Save(contact);
}
您可以使用类似的技术添加其他行为,如日志记录,异常处理和安全性。