2012-01-19 76 views
0

我剛剛實施的轉換模式討論herehere是這樣的...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); 
} 

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類...

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 
} 

最後,這裏是我的嘗試與我的團結容器註冊的翻譯類的代碼片段...

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

這種嘗試失敗。我的問題是我如何註冊一個通用的抽象類與Unity容器?僅供參考我正在使用MSUnity 2.0。

回答

1

您試圖將非通用接口映射到開放泛型類型。 Unity(或任何其他容器)如何猜測您的服務是否需要StudenFeeTranslatorRentalFeeTranslator?兩者都實現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"))); 

雖然這是很多repetetive代碼。

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>到它的實現並不是很難做到。