.net TinyIOC注射

.net TinyIOC注射,.net,dependency-injection,tinyioc,.net,Dependency Injection,Tinyioc,在微型IOC中,如何获得正在解析的类型。例如,日志记录: container.Register<ILogger>((c, p) => { return LoggerFactory.CreateLog(typeofCALLER);

在微型IOC中,如何获得正在解析的类型。例如,日志记录:

    container.Register<ILogger>((c, p) =>
                                        {
                                            return LoggerFactory.CreateLog(typeofCALLER);
                                        });
container.Register((c,p)=>
{
返回LoggerFactory.CreateLog(调用程序的类型);
});

我试图添加一个工厂来构建ILogger,但没有注入信息。

在这种情况下,简单使用TinyIoC的开放泛型功能就足够了

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);
    }
}
Consumer
类仍然需要依赖于
ILogger
,但是
ConcreteLogger
将直接实现
ILogger
成员


我看不到更好的方法,尤其是如果
ILogger
接口是固定的,因为它不是您自己的。我认为没有办法向TinyIoC请求它当前试图解析的类型,然后才能对其执行操作,因此如果您需要特定于类型的实现,则必须通过其他方式使这些类型为人所知,而泛型通常(并非总是)对此很有帮助。

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

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

TinyIoC的注册API不允许您指定一个工厂,该工厂知道当前解析类型正在注入的包含类型。下面的解决方法之所以有效,是因为TinyIoC注入了正确的
LogFactory
LogFactory
泛型实例,然后我们捕获了
LogFactory.Get()返回的正确生成的
ILog
实例。如果我们使用autofac(它确实支持您所追求的东西)进行操作,则只需额外敲击几个键,但它们不需要太多思考

假设您想在类
Foo
Bar
中进行一些登录。您只需定义一次
LogFactory
,并在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();
    }
}
公共类日志工厂{
公共日志工厂(){}//为空
public ILog Get(){return LogManager.GetLogger(typeof(T));}
}
公开课Foo{
专用只读ILog_日志;
公共Foo(LogFactory LogFactory,…){
_log=logFactory.Get();
}
}
公共类酒吧{
专用只读ILog_日志;
公共酒吧(LogFactory LogFactory,…){
_log=logFactory.Get();
}
}

此处提供的上下文很少。
LoggerFactory
的代码是什么样子的,您指的是什么类型的“注入信息”?在黑暗中拍摄时,我认为没有静态的
LoggerFactory
(或者至少不在这里直接调用它)可能会有所帮助。LoggerFactory.CreateLog只返回一个Ilogger,它是静态的,或者是以任何方式完成的。我需要被注射者的注射信息来填写TypeOfCaller,我想我明白你的意思了,
LoggerFactory
返回的实现取决于你想将
ILogger
实例注射到的类,对吧?所以和ILogger.Log(“blah”)会直接附加到Log.txt中“呼叫时间的类型”等等“,因此,当我构建ILogger时,它需要知道调用程序的类型是什么才能进行日志记录。这太棒了,有没有办法在不将ILogger转换为泛型类型的情况下实现这一点。我不想这样做,因为我想与log4net的logger impl保持兼容。您不需要更改
ILogger
,但如果没有泛型,您无法完全做到这一点。请参阅更新的答案。如果您尝试使用此选项,您可能已经注意到它实际上不起作用。这是因为TinyIoC在开放泛型方面有一个bug:
public interface ILogger<T> : ILogger
{
}
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();
    }
}