1

Tiny IOC では、解決されているタイプをどのように取得しますか。たとえば、次のようにロギングします。

    container.Register<ILogger>((c, p) =>
                                        {
                                            return LoggerFactory.CreateLog(typeofCALLER);
                                        });

ILogger を構築するためにファクトリを追加しようとしていますが、インジェクション情報がありません。

4

2 に答える 2

2

その場合、TinyIoCのOpenGenerics機能を簡単に使用するだけで十分かもしれません。

public class Consumer
{
    public Consumer(ILogger<Consumer> logger) {}
}

public interface ILogger<T>
{
    string Log(string message);
}

public class ConcreteLogger<T>:ILogger<T>
{
    public string Log(string message)
    {
        return string.Format("{0}: {1}", typeof (T), message);
    }
}

そしてします

container.Register(typeof (ILogger<>), typeof (ConcreteLogger<>));

これにより、のインスタンスがコンストラクターConcreteLogger<Consumer>に注入されます。Consumer

編集

ILogger参照が必要な場合はILogger<T>、「マーカーインターフェイス」のみを作成し、次の場所から「派生」させることができILoggerます。

public interface ILogger<T> : ILogger
{
}

Consumerクラスは引き続きに依存する必要がありますが、メンバーILogger<Consumer>を直接ConcreteLogger<T>実装します。ILogger

特にILoggerインターフェースが自分のものではないために固定されている場合は、これ以上の方法はありません。TinyIoCに現在解決しようとしているタイプを尋ねて、それに基づいて行動できるようにする方法はないと思います。したがって、タイプ固有の実装が必要な場合は、他の方法でタイプを知らせる必要があります。多くの場合(常にではありませんが)それで役に立ちます。

于 2013-03-14T16:08:09.007 に答える
1

注:私はILog私の例で使用しています。これは、log4netがそれをタイプ固有のロガークラスと呼んでいるものです。しかし、それはあなたの例の ILogger とまったく同じ方法で作成および使用されているようで、log4net はLogManager.GetLog(Type t)あなたのLoggerFactory.CreateLog(typeofCALLER).

もう少し手間がかかりますが、タイプ固有のロガーを生成するジェネリック ファクトリ クラスを作成できます。の代わりに、このファクトリ クラスをコンストラクタに挿入しIlogます。

TinyIoC の登録 API では、現在解決中の型が注入されている包含​​型を認識しているファクトリを指定できません。以下の回避策は、TinyIoC がLogFactory<Foo>orの正しいジェネリック インスタンスを挿入し、によって返されLogFactory<Bar>た正しく生成されたインスタンスをキャプチャするため機能します。autofac を使用して行った場合よりもいくつかの余分なキーストロークが必要になりますが (これは目的をサポートします)、あまり考える必要はありません。ILoglogFactory.Get()

Fooクラス、および でログを記録したいとしますBar。一度だけ定義LogFactory<T>して、Foo、Bar、およびタイプ固有の ILog インスタンスでログを記録する必要があるその他のクラスで使用します。

public class LogFactory<T> {
    public LogFactory() {} //empty
    public ILog Get() { return LogManager.GetLogger(typeof(T)); }
}

public class Foo {
    private readonly ILog _log; 

    public Foo(LogFactory<Foo> logFactory, ...) {
        _log = logFactory.Get();
    }
}

public class Bar{
    private readonly ILog _log; 

    public Bar(LogFactory<Bar> logFactory, ...) {
        _log = logFactory.Get();
    }
}
于 2015-03-20T08:06:34.610 に答える