Nic*_*ski 5 .net registration autofac
摘要:
如何contain.Resolve()在注册时将注入模块与常规呼叫结合起来?
〜更新(5小时后和反馈后)〜:
使用RegisterType <>而不是Register()并没有解决我在生产代码中的实际复杂程度,我已经更新了BitBucket上的演示代码以包含一个通用的 ISecond,其示例包括:IMagic和CreateMagic(接口,类)分别).
HG repo代码已更新,下面的PasteBin链接也已更新.
细节:
有一个包含2个依赖项的类
public SomeClassWithILogDependency(ILog log, ISecond<T> second)
Run Code Online (Sandbox Code Playgroud)
'ILog'有一个为它定义的InjectionModule,就像在文档中一样
(LogforIntegration)见帖子的底部
如果该类只有1个依赖项,则此行Autofac注册在最简单的场景中起作用:
builder.RegisterType<SomeClassWithILogDependency>()
.As<IUseILog>()
.PropertiesAutowired();
Run Code Online (Sandbox Code Playgroud)
但
我需要container.Resolve<ISecond<T>>()在注册时调用类中的更多参数,但是这样的东西不起作用:
builder.Register(
c => new SomeClassWithILogDependency(
c.Resolve<ILog>(), c.Resolve<ISecond<T>>()))
.As<IUseILog>()
.PropertiesAutowired(); //with or without this
Run Code Online (Sandbox Code Playgroud)
该c.Resolve<ILog>()是问题"该服务尚未注册."
我也试过了
SomeClassWithILogDependency(c.ResolveOptional<ILog>() //without luck...
Run Code Online (Sandbox Code Playgroud)
关于我错过了什么或完全不同的策略的任何想法?我希望解决方案不是有更多的InjectionModules ......
完整代码作为单个文件发布在PasteBin.com上
或者来自bitbucket.org的整个解决方案
hg clone https://NickJosevski@bitbucket.org/NickJosevski/autofaclog4netdemo
注塑模块代码(使这篇文章完整):
public class LogInjectionModule : Module
{
protected override void AttachToComponentRegistration(
IComponentRegistry registry, IComponentRegistration registration)
{
registration.Preparing += OnComponentPreparing;
}
private static void OnComponentPreparing(object sender, PreparingEventArgs e)
{
var t = e.Component.Activator.LimitType;
e.Parameters = e.Parameters.Union(new[]
{
new ResolvedParameter(
(p, i) => p.ParameterType == typeof (ILog),
(p, i) => LogManager.GetLogger(t))
});
}
}
Run Code Online (Sandbox Code Playgroud)
感谢bentayloruk的建议,解决方案实际上是使用:
WithParameter(/* ... */)
Run Code Online (Sandbox Code Playgroud)
所以注册码现在看起来像这样:
builder.RegisterType<SomeClassWithILogDependency<IMagic>>()
.As<IUseILog>()
.WithParameter(
(pi, c) => pi.ParameterType == (typeof(ISecond<>)),
(pi, c) => c.ResolveNamed<ISecond<IMagic>>("second")
);
Run Code Online (Sandbox Code Playgroud)
示例应用程序已更新,但不是更新的pastebin条目.
更多信息:
这是我的生产代码的简化示例,比我的实际代码稍微容易解决,其中的解决方案涉及使用具体类型进行ParameterType检查的更具体步骤,例如在此"域"中
pi.ParameterType == (typeof(CreateMagic))
Run Code Online (Sandbox Code Playgroud)
原因是我的生产SomeClassWithILogDependency没有用接口包装它的泛型参数,但我选择使示例应用程序显示问题稍有不同但产生相同的问题.
//demo:
class SomeClassWithILogDependency<TTypeOfISecond> : IUseILog
{
public SomeClassWithILogDependency(ILog log, ISecond<TTypeOfISecond> second)
}
//-------------- vs --------------
//production:
public class RealClass<TOne, TTwo>, IRealClass<TOne, TTwo>
{
public RealClass(ILog log, TOne t1, TTwo t2)
}
Run Code Online (Sandbox Code Playgroud)