Autofac:注册组件和解决取决于解析父 [英] Autofac: Register component and resolve depending on resolving parent
问题描述
我想注册一个组件基于这可能是解决该类参数来解决。 (这听起来有点混乱,所以我将展示一个例子)。
I'm wanting to register a component to resolve with parameters based on the class that it might be resolving for. (That sounds a bit confusing, so I'll show an example).
下面是一个使用记录器的对象:
Here's an object that uses a logger:
class MyObject : IMyObject
{
public ILogger Logger;
public MyObject(ILogger logger)
{
Logger = logger;
}
}
现在传递的可能是从类类不同的记录。所以,我已经得到了如何做一个相当补丁的想法如下:
Now the logger that is passed in COULD be different from class to class. So I've got a rather patched idea for how to do that below:
class MyLogger : ILogger
{
public string Name{get; protected set;}
public static ILogger GetLogger(string className)
{
Name = className;
MyLogger logger;
// Do something to choose a logger for that specific class
return logger;
}
}
所以,当我注册的Logger我希望能够告诉它的类名。我希望有办法做到这一点类似于这样:
So when I register Logger I want to be able to tell it the className. I'm hoping there's a way to do it similar to this:
ContainerBuilder builder = new ContainerBuilder();
builder.Register<MyLogger>(ctx =>
{
string className = //Get resolving class name somehow;
return MyLogger.GetLogger(className);
}).As<ILogger>();
builder.Register<MyObject>().As<IMyObject>();
var container = builder.Build();
IMyObject myObj = container.Resolve<IMyObject>();
//myObject.Logger.Name should now == "MyObject"
我想这样做,这种方式的原因是为了避免登记各班我在code autofac记录器实现。我希望能够注册所有的XML对象,并简单地有LoggerModule,添加此注册。
The reason I want to do it this way is to avoid registering each class I implement with a logger with autofac in code. I want to be able to register all of the objects in xml, and simply have a LoggerModule, that adds this registration.
在此先感谢!
推荐答案
下面是我做的(ILog的只是我身边的log4net自己的包装):
Here's what I do (ILog is just my own wrapper around log4net):
public class LoggingModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register((c, p) => GetLogger(p.TypedAs<Type>()));
}
protected override void AttachToComponentRegistration(
IComponentRegistry registry, IComponentRegistration registration)
{
registration.Preparing +=
(sender, args) =>
{
var forType = args.Component.Activator.LimitType;
var logParameter = new ResolvedParameter(
(p, c) => p.ParameterType == typeof (ILog),
(p, c) => c.Resolve<ILog>(TypedParameter.From(forType)));
args.Parameters = args.Parameters.Union(new[] {logParameter});
};
}
public static ILog GetLogger(Type type)
{
return new Log4NetLogger(type);
}
}
public interface ILog
{
void Debug(string format, params object[] args);
void Info(string format, params object[] args);
void Warn(string format, params object[] args);
void Error(string format, params object[] args);
void Error(Exception ex);
void Error(Exception ex, string format, params object[] args);
void Fatal(Exception ex, string format, params object[] args);
}
public class Log4NetLogger : ILog
{
private readonly log4net.ILog _log;
static Log4NetLogger()
{
XmlConfigurator.Configure();
}
public Log4NetLogger(Type type)
{
_log = LogManager.GetLogger(type);
}
public void Debug(string format, params object[] args)
{
_log.DebugFormat(format, args);
}
public void Info(string format, params object[] args)
{
_log.InfoFormat(format, args);
}
public void Warn(string format, params object[] args)
{
_log.WarnFormat(format, args);
}
public void Error(string format, params object[] args)
{
_log.ErrorFormat(format, args);
}
public void Error(Exception ex)
{
_log.Error("", ex);
}
public void Error(Exception ex, string format, params object[] args)
{
_log.Error(string.Format(format, args), ex);
}
public void Fatal(Exception ex, string format, params object[] args)
{
_log.Fatal(string.Format(format, args), ex);
}
}
这篇关于Autofac:注册组件和解决取决于解析父的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!