2
votes

I have a problem with resolving a Generic Interface mapped to none generic Type.

Registration:

UnityContainer.RegisterType<IHandle<SomeEvent>, SomeHandler>();
//UnityContainer.RegisterType(typeof(IHandle<SupplierApprovedEvent>), typeof(TestHandler));

This is how i try to resolve it without success:

 public static void GenericResolver<T>(T args) where T : IDomainEvent
        {
            var handlerType = typeof(IHandle<>).MakeGenericType(args.GetType());
            var firstTry = container.GetServices(handlerType);// Resolve fails
            var secondTry = container.GetServices(typeof(IHandle<T>)); // Resolve fails

            var casted = args as IDomainEvent;
            var handlerType2 = typeof(IHandle<>).MakeGenericType(casted.GetType());
            var thirdTry = container.GetServices(handlerType2);// Resolve fails

            var handlerType3 = typeof(IHandle<>).MakeGenericType(typeof(T));
            var fourthTry = container.GetServices(handlerType3);// Resolve fails
        }

My interfaces:

public interface IDomainEvent {}

public interface IHandle<T>: IHandle where T : IDomainEvent
{
    void Handle(T args);
}

public interface IHandle
{
    void Handle(IDomainEvent args);
}

Interface implementation:

public class SomeHandler: IHandle<SomeEvent>
{
    public void Handle(IDomainEvent args)
    {
        Handle(args as SomeEvent);
    }

    public void Handle(SomeEvent args)
    {
        //DO SOMETHING
    }
}

What do I miss here :!?

UPDATE:

1.there are no exceptions.

2.GetService is returning null.

3.This resolve works fine but its not what i want:

var itsTypeofSomeHangled =(SomeHandler)injector.GetService(typeof(IHandle<SomeEvent>));

4.container in the example is UnityDependencyResolver which inherits IDependencyResolver. This is the reason why i call methods GetServices and GerSevice

UPDATE2: It turns out that the problem is in GetServices (ResolveAll). This line works perfectly, but i have more than one implementation of this Gereric Interface.

var handlerType = typeof(IHandle<>).MakeGenericType(args.GetType());
var xxxx = (IHandle)container.GetService(handlerType);
1
Is GetServices an extension method that you created yourself? Or do you mean to use Resolve instead? - Yacoub Massad
Why do you call container.GetServices instead of container.Resolve? - Steven
container is UnityDependencyResolver exposed as IDependencyResolver. Thats why its GetService instead of Resolve - IIvanov
You say "resolve fails" but do didn't add the exception details (message, type, full stack trace) to your question. - Steven
Why do you use GetServices instead of GetService? - Yacoub Massad

1 Answers

1
votes

I found what is the problem. Unity resolve all does not work the way i expect in my example. Scott Chamberlain explanation in this topic covers it.

Solution:

    var handlerType = typeof(IHandle<>).MakeGenericType(args.GetType());
    var handlers = resolver.Container.Registrations
                       .Where(x => x.RegisteredType.IsGenericType && x.RegisteredType == handlerType)
                       .Select(x => (IHandle)resolver.GetService(x.RegisteredType));

    foreach (IHandle item in handlers)
    {
        item.Handle(args);
    }

Basically what i did here is to query the container registration to look for my handler type. Than in the .Select i call GetService(Resolve) with the specific registration.RegisteredType parameter and of course cast it. Than in the foreach its obvious...