Autofac:向带有参数的委托(delegate)注册添加装饰器

标签 autofac

我正在尝试使用 autofac 管理 WCF 客户端的注册。

我需要解决Func<MachineEndpoint, IFooService> ,所以我使用以下方法注册了该服务:

builder.Register((c, p) => FooService(c, p.TypedAs<MachineEndpoint>())).UseWcfSafeRelease()

FooService 在哪里:

private IJobService FooService(IComponentContext c, MachineEndpoint endpoint) {...}

这工作正常,但我想添加一个装饰器来处理某些安全错误,所以我尝试了以下方法:

builder.Register((c, p) => FooService(c, p.TypedAs<MachineEndpoint>())).UseWcfSafeRelease().Named<IFooService>("simple foo service");
builder.RegisterDecorator<IFooService>((c, p, inner) => Wrap(inner, p.TypedAs<MachineEndpoint>(), c.Resolve<CertificateLookupCache>()), "simple foo service");

但我得到了 DependecyResolutionException:

Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details. ---> System.InvalidOperationException: Sequence contains no elements
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at MyModule.<Load>b__4(IComponentContext c, IEnumerable`1 p) in MyModule.cs:line 30 (the first line above)
   at Autofac.Builder.RegistrationBuilder.<>c__DisplayClass1`1.<ForDelegate>b__0(IComponentContext c, IEnumerable`1 p)
   at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Features.LightweightAdapters.LightweightAdapterRegistrationSource.<>c__DisplayClass3.<RegistrationsFor>b__1(IComponentContext c, IEnumerable`1 p)
   at Autofac.Builder.RegistrationBuilder.<>c__DisplayClass1`1.<ForDelegate>b__0(IComponentContext c, IEnumerable`1 p)
   at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   --- End of inner exception stack trace ---

Server stack trace:
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters)
   at lambda_method(Closure , MachineEndpoint )

如何注册这些函数,以便可以获得传递给 WCF 客户端对象和装饰器的 MachinEndpoint 参数?

最佳答案

该问题是由您的参数使用引起的:p.TypedAs<MachineEndpoint>()因为当前 Autofac 存在一个限制,即 RegisterDecorator创建inner时不传递参数装饰对象。

所以当它尝试创建 inner 时与 (c, p) => FooService(c, p.TypedAs<MachineEndpoint>()) (IEnumerable<Parameter> p)将为空,因此您会得到异常。

你基本上可以做两件事:

您可以尝试以不使用 p.TypedAs<MachineEndpoint>() 的方式重新组织代码。不再了。

或者

因为你的IFooService无论如何,一个没有多个实现的 WCF 服务,您可以“手动”注册您的装饰器:

builder.Register((c, p) => FooService(c, p.TypedAs<MachineEndpoint>()))
       .UseWcfSafeRelease()
       .Named<IFooService>("simple foo service");
builder.Register<IFooService>((c, p) => 
     Wrap(c.ResolveNamed<IFooService>("simple foo service",
          TypedParameter.From(p.TypedAs<MachineEndpoint>())),
          p.TypedAs<MachineEndpoint>(),
          c.Resolve<CertificateLookupCache>()));

关于Autofac:向带有参数的委托(delegate)注册添加装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15476509/

相关文章:

.net - Autofac InstancePerMatchingLifetimeScope

c# - Autofac 结合 RegisterApiControllers 在 ApiController 上注入(inject)属性

c# - 依赖注入(inject) : by hand vs autofac

autofac - 如何使用 Autofac 注册(无限)类型层次结构?

c# - 使用 Autofac 创建具有依赖关系的类的实例

asp.net-mvc - ASP.NET 中的 NHibernate 与 Autofac (MVC) : ITransaction

c# - 如何确定 Autofac 在解析时使用哪个构造函数

c# - Autofac 生命周期和匹配生命周期范围内的默认提供程序

c# - 使用 Autofac 的 Windows 服务保留引用

asp.net-mvc-3 - 将 IoC 容器与 MVC3 结合使用的性能开销