我有一个更简单的"ServiceHelper"类,它在构造函数中接受两个参数:
public ServiceHelper(ILogger<ServiceHelper> log, string serviceName)
Run Code Online (Sandbox Code Playgroud)
(用于NOG的ILogger通用包装器,Autofac提供的很好,而serviceName是用于控制我需要在运行时提供的Windows服务的名称.)
我在使用Autofac在运行时以不同的服务名称传递如何创建此类的新实例时遇到了麻烦.这样的事情当然不起作用,因为我需要在运行时指定不同的服务名称:
builder.RegisterType<ServiceHelper>().As<IServiceHelper>().WithParameter(new NamedParameter("serviceName", null)).InstancePerDependency();
Run Code Online (Sandbox Code Playgroud)
从我所读到的,它是一个坏习惯传递容器并手动调用Resolve(AutoFac警告的服务定位器"反模式"),或者是它?如果我这样做那么我就可以做到
container.Resolve<ServiceHelper>(new NamedParameter("serviceName", "some service name"));
Run Code Online (Sandbox Code Playgroud)
但是,即使到目前为止,我也不太确定如何让Autofac将容器注入类中,它只需要注册自己的确切方式,就像这样?然后让我的类在他们的构造函数中需要一个IContainer?(这是使用构造函数注入的C#服务)
builder.RegisterType<Container>().As<IContainer>().InstancePerDependency();
Run Code Online (Sandbox Code Playgroud)
我也读到了委托工厂,但似乎并没有摆脱必须通过容器.
实际上我使用ServiceHelper的大多数类只需要1或2个ServiceHelper来获取特定的服务名称,所以它不像我使用意外的serviceName参数制作数千个,这只是让我头疼一点.
注意:更新了建议的改进,更接近但仍然不完全!
与此问题类似 - 使用Autofac传递NLog的声明类的类型 - 我试图将NLog实例注入我的存储库类.
接口:
public interface ILogger<T>
where T: class
{
...
}
Run Code Online (Sandbox Code Playgroud)
执行:
public class NLogger<T> : ILogger<T>
where T: class
{
private readonly Logger _logger;
public NLogger()
{
_logger = LogManager.GetLogger(typeof(T).FullName);
}
public void Debug(string message)
{
_logger.Debug(message);
}
...
}
Run Code Online (Sandbox Code Playgroud)
在Autofac注册为:
builder.RegisterGeneric(typeof (NLogger<>)).As(typeof (ILogger<>));
Run Code Online (Sandbox Code Playgroud)
使用断点,我看到Autofac正在创建一堆ILogger/NLogger,其中包含所有各种存储库的正确类型,但生成的日志显示为callsite为"NLog.LoggerImpl.Write".
谢谢你的帮助!
使用泛型的工作解决方案:
public class NLogger<T> : ILogger<T>
where T: class
{
private readonly Logger _logger;
public NLogger()
{
_logger = LogManager.GetLogger(typeof(T).FullName);
}
public void Debug(string message)
{
_logger.Log(typeof(T), new …Run Code Online (Sandbox Code Playgroud)