2012-01-19 14 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クラスから無関係のメソッドを差し引いたものです。この試みは失敗した

container.RegisterType(typeof (ITranslator), typeof (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コンテナに登録できますか?私はMSUnity 2.0を使用しています。

答えて

1

非ジェネリックインターフェイスを公開ジェネリックタイプにマップしようとしています。あなたのサービスにStudenFeeTranslatorまたはRentalFeeTranslatorが必要かどうかUnity(または他のコンテナ)はどのように推測する必要がありますか?どちらも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); 

これは一つに(StudentFeeTranslator用などの名前がStudentFeeTranslatorだろう)実装するクラスの名前でITranslatorのすべての実装を登録します行く。

インターフェイスを汎用化すると、プロパティに注入する方が簡単になります。 ITranslator<X, Y>をその実装にマッチングさせることは実際には困難ではない。