MSUnity - 注册类型 - 通用抽象类

时间:2012-01-19 20:50:28

标签: unity-container

我刚刚实施了所讨论的翻译模式herehere ...

ITranslator界面......

public interface ITranslator
{
    bool CanTranslate(Type targetType, Type sourceType);
    bool CanTranslate<TTarget, TSource>();
    object Translate(Type targetType, object source);
    TTarget Translate<TTarget>(object source);
}

... Translator.cs

public abstract class Translator<TBusinessEntity, TServiceEntity> : ITranslator where TBusinessEntity : class
                                                                                where TServiceEntity : class
{
    public bool CanTranslate(Type targetType, Type sourceType)
    {
        return (targetType == typeof(TBusinessEntity) && sourceType == typeof(TServiceEntity)) ||
               (targetType == typeof(TServiceEntity) && sourceType == typeof(TBusinessEntity)); 
    }

    public bool CanTranslate<TTarget, TSource>()
    {
        return CanTranslate(typeof (TTarget), typeof (TSource));
    }

    public TTarget Translate<TTarget>(object source)
    {
        return (TTarget)Translate(typeof(TTarget), source);
    }

    public object Translate(Type targetType, object source)
    {
        if (targetType == typeof(TBusinessEntity))
            return ServiceToBusiness((TServiceEntity)source);

        if (targetType == typeof(TServiceEntity))
            return BusinessToService((TBusinessEntity)source);
        throw new System.ArgumentException("Invalid type passed to Translator", "targetType");  
    }

    protected abstract TServiceEntity BusinessToService(TBusinessEntity value);
    protected abstract TBusinessEntity ServiceToBusiness(TServiceEntity value);
    protected abstract List<TServiceEntity> BusinessToService(List<TBusinessEntity> valueList);
    protected abstract List<TBusinessEntity> ServiceToBusiness(List<TServiceEntity> valueList);
}

这是我的StudentFeeTranslator类,它实现了Translator抽象方法......

public class StudentFeeTranslator : Translator<StudentFee, StudentFeeType>
{
    #region Overrides of Translator<StudentFee,StudentFeeType>

    protected override StudentFeeType BusinessToService(StudentFee value)
    {
        return new
            StudentFeeType
                   {
                        StudentFeeId = value.StudentFeeRefId,
                        FeeId = value.FeeRefId,
                        StudentId = value.StudentRefId,
                        SchoolId = value.SchoolRefId,
                        FeeDate = value.AssessmentDate,
                        FeeAmount = value.AssessmentAmount,
                        Balance = value.UnpaidBalance,
                        FeeTypeId = value.FeeType,
                        Description = value.FeeDescription
                    };
    }

    protected override StudentFee ServiceToBusiness(StudentFeeType value)
    {
        return new
            StudentFee
                   {
                        StudentFeeRefId = value.StudentFeeId,
                        FeeRefId = value.FeeId,
                        StudentRefId = value.StudentId,
                        SchoolRefId = value.SchoolId,
                        AssessmentDate = value.FeeDate,
                        AssessmentAmount = value.FeeAmount,
                        UnpaidBalance = value.Balance,
                        FeeType = (Byte)value.FeeTypeId,
                        FeeDescription = value.Description
                    };
    }

    protected override List<StudentFeeType> BusinessToService(List<StudentFee> valueList)
    {
        return valueList.Select(BusinessToService).ToList();
    }

    protected override List<StudentFee> ServiceToBusiness(List<StudentFeeType> valueList)
    {
        return valueList.Select(ServiceToBusiness).ToList();
    }

    #endregion
}

接下来是我的StudentFeeService类减去不相关的方法。请注意标记为注入的转换器属性...

public partial class StudentFeeService : IStudentFeeService
{
    #region Public Members

    [Dependency]
    public ITranslator Translator { get; set; }

    #endregion

    #region Private Methods

    private List<StudentFeeType> ConvertStudentFeeListToListOfStudentFeeTypes(List<StudentFee> studentFees)
    {
        return Translator.Translate<List<StudentFeeType>>(studentFees);
    }

    #endregion
}

最后,这是我尝试使用Unity容器注册Translator类的代码片段...

container.RegisterType(typeof (ITranslator), typeof (Translator<,>));

此尝试失败。我的问题是如何在Unity容器中注册通用抽象类?仅供参考我正在使用MSUnity 2.0。

1 个答案:

答案 0 :(得分:1)

您正在尝试将非泛型接口映射到开放泛型类型。 Unity(或任何其他容器)如何猜测您的服务是需要StudenFeeTranslator还是RentalFeeTranslator?两者都实现ITranslator,这就是容器可以看到的全部内容。

您可以注册ITranslator的所有具体实现,为其提供个人名称。这是所有容器支持的东西。然后让Unity将特定的依赖项注入到服务的Translator属性中。像

这样的东西
container.RegisterType(typeof(ITranslator), typeof(StudentFeeTranslator), "StudentFee");
container.RegisterType(typeof(ITranslator), typeof(RentalFeeTranslator), "RentalFee");
container.RegisterType(typeof(IStudentFeeService), typeof(StudentFeeService), 
  new InjectionProperty("Translator", new ResolvedParameter<ITranslator>("StudentFee")));

虽然这是很多重复的代码。

Unity没有开箱即用的注册约定。但TecX project包含一个增强的配置引擎,允许您执行以下操作:

ConfigurationBuilder builder = new ConfigurationBuilder();
builder.Scan(
  scanner =>
    {
      scanner.AddAllImplementationsOf(typeof(ITranslator);
      scanner.AssembliesFromApplicationBaseDirectory();
    });
container.AddExtension(builder);

这将一次性注册ITranslator的所有实现以及实现类的名称(例如,StudentFeeTranslator的名称将是StudentFeeTranslator)。

如果您使界面通用,则更容易注入属性。将ITranslator<X, Y>与其实现相匹配并不是很难。