.net - 如何仅使用 Autofac 注入(inject)一些构造函数参数并结合使用 InjectionModule

标签 .net registration autofac

摘要:

如何将注入(inject)模块与常规 contain.Resolve() 结合使用注册电话?

~ Update (5 hours later and after feedback)~ :

The use of RegisterType<> as opposed to Register() does not solve the actual complexity level I have in production code, I have updated the demo code on BitBucket to include a generic ISecond, with examples of: IMagic and CreateMagic (interface, class respectively).

The HG repo code has been updated, as has the PasteBin link below.



详情:

有一个类有 2 个依赖项
public SomeClassWithILogDependency(ILog log, ISecond<T> second)

'ILog' 为其定义了一个 InjectionModule,就像在文档中一样

( LogforIntegration ) 见帖子底部

如果该类只有 1 个依赖项,那么这行 Autofac 注册在最简单的情况下工作:
builder.RegisterType<SomeClassWithILogDependency>()
.As<IUseILog>()
.PropertiesAutowired();

但是

我需要调用container.Resolve<ISecond<T>>()在注册类上的更多参数,但这样的事情不起作用:
builder.Register(
    c => new SomeClassWithILogDependency(
        c.Resolve<ILog>(), c.Resolve<ISecond<T>>()))
    .As<IUseILog>()
    .PropertiesAutowired(); //with or without this
c.Resolve<ILog>()是“该服务尚未注册”的问题。

我也试过
SomeClassWithILogDependency(c.ResolveOptional<ILog>() //without luck...

关于我错过了什么或完全不同的策略的任何想法?我希望解决方案是不要有更多的 InjectionModules ...

完整代码发布在 PasteBin.com作为一个文件

来自 bitbucket.org 的完整解决方案

hg clone https://NickJosevski@bitbucket.org/NickJosevski/autofaclog4netdemo



注入(inject)模块代码(使这篇文章完整):
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))
            });
    }
}

最佳答案

感谢 bentayloruk的建议,解决方案实际上是使用:

WithParameter(/* ... */)

所以注册码现在看起来像这样:
builder.RegisterType<SomeClassWithILogDependency<IMagic>>()
.As<IUseILog>()
.WithParameter(
    (pi, c) => pi.ParameterType == (typeof(ISecond<>)),
    (pi, c) => c.ResolveNamed<ISecond<IMagic>>("second")
    );

The sample application has been updated, but not the pastebin entry.



更多信息:

这是我的生产代码的简化示例,比我的实际代码更容易解​​决,那里的解决方案涉及一个更具体的步骤,即使用具体类型进行 ParameterType 检查,例如在这个“域”中
pi.ParameterType == (typeof(CreateMagic))

这样做的原因是我的生产 SomeClassWithILogDependency 没有使用接口(interface)包装其通用参数,但我选择使显示问题的示例应用程序操作略有不同但产生相同的问题。
//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)
}

关于.net - 如何仅使用 Autofac 注入(inject)一些构造函数参数并结合使用 InjectionModule,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6183700/

相关文章:

asp.net-mvc - 在 MVC 5 应用程序中使用 autofac 注入(inject) SignalR Hub 的依赖项

c# - 是否可以使用 .NET 跟踪文件操作?

c# - 如何搜索和导航 XML 节点

c# - .NET 4.5 中的任务与线程

c# - 如何将 WindowsIdentity 转换为 NetworkCredential?

php - 使用 session 的多步注册表 PHP/MySql

java - 将对象传递给方法?

php - 用户注册问题

c# - Autofac:解析类型的所有实例

c# - 在AutoFac容器中针对 View 注册WPF ViewModel的最佳方法是什么?