Unity - 如何使用基本类型注册类型

时间:2011-04-13 23:03:34

标签: c# .net unity-container enterprise-library ioc-container

我有一个基类和一些派生类。基类包含需要注入的属性。如何配置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吗?

2 个答案:

答案 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);
}

您可以使用类似的技术添加其他行为,如日志记录,异常处理和安全性。