SimpleInjector:通过适配器注册收集

时间:2019-05-28 07:01:05

标签: c# dependency-injection simple-injector

使用SimpleInjector,您可以注册类型的集合:

interface ILogger { }
class FileLogger : ILogger { }
class SqlLogger : ILogger { }

// usage
var container = new Container();
container.Collection.Register<ILogger>(typeof(FileLogger), typeof(SqlLogger));
container.GetAllInstances<ILogger>(); // returns both ILoggers

有了这些,我想用抽象ILogger包装这样的MyLogger,可以在整个应用程序中使用:

interface MyLogger {
}

class LoggerAdapter : MyLogger {
    public LoggerAdapter(ILogger logger) { }
}

但是我无法通过容器将记录器适配器注册为ILogger s的已注册集合中的一个集合:

var container = new Container();
container.Collection.Register<ILogger>(typeof(FileLogger), typeof(SqlLogger));
container.Collection.Register<MyLogger>(typeof(ILogger));
// ArgumentException: The supplied type ILogger does not inherit from MyLogger.
// Parameter name: serviceTypes

虽然明确显示了异常消息(ILogger并非继承自LoggerAdapter),但我觉得SimpleInjector应该能够通过LoggerAdapter来创建ILogger s,只需将这些ILogger注入LoggerAdapter中即可。

是否有一种干净的方法来注册此类适配器的集合?

1 个答案:

答案 0 :(得分:1)

这里有多种解决方案。我想到的第一件事是将适配器更改为接受记录器列表:

class LoggerAdapter : MyLogger
{
    public LoggerAdapter(IEnumerable<ILogger> loggers) { }
}

这可能是一个更令人愉悦的解决方案,因为它允许您将MyLogger单独注入到消费者中,而不必注入MyLogger实例的集合。

如果您确实需要MyLogger的列表,则可以按以下步骤手动注册集合:

container.RegisterSingleton<IEnumerable<MyLogger>>(
    () => container.GetAllInstances<ILogger>().Select(logger => new LoggerAdapter(logger)));