2

Unity Configuration を使用してクラス プロパティに依存関係を追加しようとしていますが、注入しようとしている型も汎用的です。

私はインターフェースを持っています

public interface ISendMessage
{
    void Send(string contact, string message);
}

クラス

public class EmailService : ISendMessage
{
    public void Send(string contact, string message)
    {
        // do
    }
}

クラス

public class MessageService<T> where T : ISendMessage
{          
}

他のクラスでコンストラクター注入を介して使用してみます

public MyService(MessageService<ISendMessage> messageService)
{
}

MessageService<EmailService>の代わりにどのように注入しMessageService<ISendMessage>ますか?

私は app.config 経由でそれをやってみます

<alias alias="MessageService'1" type="MyNamespace.MessageService'1, MyAssembly" />
    <alias alias="EmailMessageService'1" type="MyNamespace.MessageService'1[[MyNamespace.EmailService, MyAssembly]], MyAssembly" />

エラーが発生します

タイプ名またはエイリアス MessageService'1 を解決できませんでした。構成ファイルを確認して、このタイプ名を確認してください。

そして、どのようにMessageService<T>実装パラメータを渡すことができMessageService<EmailService>ますか?

ありがとう

アップデート

クラスを次のように変更しました。

public class MessageService<T> where T : ISendMessage
    {
        private T service;

        [Dependency]
        public T Service
        {
            get { return service; }
            set { service = value; }
        }
}

構成を使用する

<alias alias="ISendMessage" type="MyNamespace.ISendMessage, MyAssembly" />
    <alias alias="EmailService" type="MyNamespace.EmailService, MyAssembly" />

<register type="ISendMessage" mapTo="EmailService">
        </register>

できます :-)

4

1 に答える 1

6

MessageService<ISendMessage>aを a に単純にキャストすることはできませんMessageService<EmailService>MessageService<T>これが機能するには、 がバリアントである必要があります。バリアンスは、インターフェイス (およびデリゲート) でのみサポートされています。これは Unity の問題ではなく、.NET フレームワーク (および 4.0 以降の C# でのサポート) の「制限」です。したがって、次のインターフェースを実装する必要があります。

// note the 'out' keyword!!
public interface IMessageService<out T> 
    where T : ISendMessage
{
    T GetSendMessage();
}

MessageService<T>クラスは、このインターフェースを実装する必要があります。しかし、このコードを使用しても、Unity はこれを自動的に挿入しません。2 つのタイプの間でマッピングを作成する必要があります。たとえば、これは可能な登録です:

container.Register<MessageService<ISendMessage>>(
    new InjectionFactory(c =>
        c.Resolve<MessageService<EmailService>>())); 

コードベースの構成を使用していることに注意してください。XML 構成は壊れやすく、エラーが発生しやすく、強力ではなく、保守が難しいため、できるだけ XML ベースの構成を使用しないでください。展開中または展開後に実際に必要な型のみを登録します (個人的には、その場合でも DI コンテナーの XML API は使用しません)。

于 2012-06-26T13:17:47.600 に答える