Search code examples
c#dependency-injectionunity-containerninject

Refactor C# Class with Generics from IUnityContainer to Ninject


I would like to move away from the Unity NuGet package for Dependency Injection and switch to Ninject since Unity is no longer being maintained. I was wondering if someone might be able to help me refactor the following Mediator class to use Ninject instead of IUnityContainer?

For example, should I be replacing the IUnityContainer with the Ninject StandardKernel?

Will I need to use the Ninject Bind method rather than the Unity Resolve method?

Mediator.cs

public sealed class Mediator : IMediator
{
    private readonly IUnityContainer _container;

    public Mediator(IUnityContainer container)
    {
        _container = container;
    }

    public TResponse Request<TResponse>(IQuery<TResponse> query)
    {
        var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResponse));
        dynamic handler = _container.Resolve(handlerType);

        return handler.Handle((dynamic)query);
    }

    public TResult Send<TResult>(ICommand<TResult> command)
    {
        var handlerType = typeof(ICommandHandler<,>).MakeGenericType(command.GetType(), typeof(TResult));
        dynamic handler = _container.Resolve(handlerType);

        return handler.Handle((dynamic)command);
    }
}

IMediator.cs

public interface IMediator
{
    TResponse Request<TResponse>(IQuery<TResponse> query);
    TResult Send<TResult>(ICommand<TResult> command);
}

IQuery.cs

public interface IQuery<out TResponse> { }

IQueryHandler.cs

public interface IQueryHandler<in TQuery, out TResponse> where TQuery : IQuery<TResponse>
{
    TResponse Handle(TQuery query);
}

ICommand.cs

public interface ICommand<out TResult> { }
public interface ICommand { }

ICommandHandler

public interface ICommandHandler<in TCommand, out TResult> where TCommand : ICommand<TResult>
{
    TResult Handle(TCommand command);
}

public interface ICommandHandler<in TCommand> where TCommand : ICommand
{
    void Handle(TCommand command);
}

Solution

  • Mediator.cs

    public sealed class Mediator : IMediator
    {
        private readonly IKernel _container;
    
        public Mediator(IKernel container)
        {
            _container = container;
        }
    
        public TResponse Request<TResponse>(IQuery<TResponse> query)
        {
            var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResponse));
    
            var request = _container.CreateRequest(handlerType, null, new Parameter[0], true, true);
            var handlerList = _container.Resolve(request);
            dynamic handler = handlerList.SingleOrDefault();
    
            return handler.Handle((dynamic)query);
        }
    
        public TResult Send<TResult>(ICommand<TResult> command)
        {
            var handlerType = typeof(ICommandHandler<,>).MakeGenericType(command.GetType(), typeof(TResult));
    
            var request = _container.CreateRequest(handlerType, null, new Parameter[0], true, true);
            var handlerList = _container.Resolve(request);
            dynamic handler = handlerList.SingleOrDefault();
    
            return handler.Handle((dynamic)command);
        }
    }