2013-03-18 3 views
2

Я пытаюсь управлять регистрацией моих клиентов WCF с помощью autofac.Autofac: добавление декоратора к регистрации делегата, который принимает параметры

мне нужно решить 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) 

Как я могу зарегистрировать эти функции, так что я могу получить параметр MachinEndpoint передается как объект клиента WCF и декоратора?

ответ

1

Проблема возникает из-за использования вашего параметра: 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>())); 
+0

спасибо, второй вариант работает хорошо –

Смежные вопросы