Is it possible to register an open shared delegate in autofac?

I want to register a generic delegate that resolves itself at runtime, but I cannot find a way to do this in generics.

For a delegate that looks like this:

public delegate TOutput Pipe<in TInput, out TOutput>(TInput input); 

And given a discretely registered delegate that looks like this:

 public class AnonymousPipe<TInput, TOutput> { public Pipe<TInput, TOutput> GetPipe(IContext context) {...} 

I want to register a function line by line:

 builder.RegisterGeneric(typeof(Pipe<,>)).As(ctx => { var typeArray = ctx.RequestedType.GetGenericArguments(); // this can be memoized var pipeDefinition = ctx.Resolve(typeof(AnonymousPipe<,>).MakeGenericType(typeArray)); return pipeDefinition.GetPipe(ctx); 

I canโ€™t find a way to provide an implementation of generic as a parameter in Autofac - I can just miss something. I know that I can do this through a shared object or interface, but I want to stick with the ease of the delegate. This makes unit testing super easy when entering this data.

Any thoughts? I have to do discrete registrations at the moment (one type combination and no generics).

+4
source share
1 answer

I can only find the original registration solution (universal hammer in Autofac.)

 class PipeSource : IRegistrationSource { public bool IsAdapterForIndividualComponents { get { return true; } } public IEnumerable<IComponentRegistration> RegistrationsFor( Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) { var swt = service as IServiceWithType; if (swt == null || !swt.ServiceType.IsGenericType) yield break; var def = swt.ServiceType.GetGenericTypeDefinition(); if (def != typeof(Pipe<,>)) yield break; var anonPipeService = swt.ChangeType( typeof(AnonymousPipe<,>).MakeGenericType( swt.ServiceType.GetGenericArguments())); var getPipeMethod = anonPipeService.ServiceType.GetMethod("GetPipe"); foreach (var anonPipeReg in registrationAccessor(anonPipeService)) { yield return RegistrationBuilder.ForDelegate((c, p) => { var anon = c.ResolveComponent(anonPipeReg, p); return getPipeMethod.Invoke(anon, null); }) .As(service) .Targeting(anonPipeReg) .CreateRegistration(); } } } 

Then:

 builder.RegisterSource(new PipeSource()); 

Now Iโ€™m sure that I canโ€™t type this code into a web page and compile and run it, but it can come nearer :)

+4
source

Source: https://habr.com/ru/post/1379354/


All Articles