TinyIOC构造函数注入

时间:2013-02-06 22:15:09

标签: .net dependency-injection tinyioc

在Tiny IOC中,如何获得正在解决的类型。例如记录:

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

我正在尝试添加工厂来构建ILogger,但没有注入信息。

2 个答案:

答案 0 :(得分:2)

在这种情况下,简单地使用TinyIoC的Open Generics功能就足够了。

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询问它当前正在尝试解决的类型,然后才能对其采取行动,因此如果您需要特定类型的实现,则必须通过其他方式了解类型 - 并且泛型经常(并非总是)对此有所帮助。

答案 1 :(得分:1)

注意:我在我的示例中使用ILog,这就是log4net称之为特定类型的记录器类。但它似乎以与示例中的ILogger完全相同的方式创建和使用,并且log4net的LogManager.GetLog(Type t)与您的LoggerFactory.CreateLog(typeofCALLER)类似。

它可以做多一点工作,但您可以创建一个生成特定类型记录器的通用工厂类。将此工厂类注入构造函数而不是Ilog

TinyIoC的注册API不允许您指定一个工厂,该工厂知道正在注入当前解析类型的包含类型。以下解决方法有效,因为TinyIoC会注入LogFactory<Foo>LogFactory<Bar>的正确通用实例,然后我们捕获ILog返回的正确生成的logFactory.Get()实例。一些额外的击键比我们使用autofac做的更多 - 这确实支持你所追求的 - 但他们不需要太多考虑。

假设您要在班级FooBar中进行一些登录。您只需定义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();
    }
}