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。
答案 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>
与其实现相匹配并不是很难。