MSUnity-注册类型-泛型抽象类



我刚刚实现了这里和这里讨论的转换器模式,就像…

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

翻译器.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类减去不相关的方法。请注意标记为要注入的Translator属性。。。

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。

您正在尝试将非泛型接口映射到开放泛型类型。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项目包含一个增强的配置引擎,可以让你做这样的事情:

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

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

如果您将接口设为泛型,那么将更容易注入到属性中。将ITranslator<X, Y>与其实现相匹配其实并不难。

最新更新