具有 ninject 和通用接口的自动映射器将无法工作(错误 activating/no 匹配绑定可用)

Automapper with ninject and generic interface won't work (error activating/no matching bindings available)

我正在尝试将 automapper 与 ninject 和通用接口抽象 class 结合使用。不过好像不行。

您将在下面找到我正在尝试使用的代码。我错过了什么?

IMapper

 public interface IMapper<in TTypeFrom, TTypeTo>
{
    TTypeTo Map(TTypeFrom typeFrom);
    List<TTypeTo> Map(IEnumerable<TTypeFrom> itemToMap);
}
public abstract class Mapper<TTypeFrom, TTypeto> : IMapper<TTypeFrom, TTypeto>
{
    private readonly IMappingEngine _mappingEngine;
    private readonly IConfiguration _configuration;

    protected Mapper(IMappingEngine mappingEngine, IConfiguration configuration)
    {
        _mappingEngine = mappingEngine;
        _configuration = configuration;

        _configuration.CreateMap<TTypeFrom, TTypeto>();
    }

    public TTypeto Map(TTypeFrom typeFrom)
    {
        return Map<TTypeFrom, TTypeto>(typeFrom);
    }
    protected TTo Map<TFrom, TTo>(TFrom itemToMap)
    {
        return _mappingEngine.Map<TFrom, TTo>(itemToMap);
    }

    public List<TTypeto> Map(IEnumerable<TTypeFrom> itemToMap)
    {
        return Map<TTypeFrom, TTypeto>(itemToMap);
    }
    protected List<TTo> Map<TFrom, TTo>(IEnumerable<TFrom> itemsToMap)
    {
        return itemsToMap.Select(Map<TFrom, TTo>).ToList();
    }
}

CategoryRepresentationMapper

public interface ICategoryRepresentationMapper : IMapper<CategoryRepresentation, CategoryRepresentationDto>
{

}
public class CategoryRepresentationMapper : Mapper<CategoryRepresentation, CategoryRepresentationDto>, ICategoryRepresentationMapper
{
    public CategoryRepresentationMapper(IMappingEngine mappingEngine, IConfiguration configuration) : base(mappingEngine, configuration)
    {
    }
}

设置 ninject

IKernel kernel = new StandardKernel();


        Mapper.Initialize(map =>
        {
            map.ConstructServicesUsing(f => kernel.Get(f));
        });

        kernel.Bind<IMappingEngine>().ToMethod(x => Mapper.Engine);
        kernel.Bind<IConfigurationProvider>().ToMethod(x => Mapper.Engine.ConfigurationProvider);
        kernel.Bind<IConfiguration>().ToMethod(x => Mapper.Configuration);

        kernel.Bind(
          x =>
              x.FromAssemblyContaining(typeof(IMapper<,>))
                  .SelectAllClasses()
                  .InheritedFrom(typeof(IMapper<,>))
                  .BindAllInterfaces());

        var categoryRepresentationMapper = kernel.Get<ICategoryRepresentationMapper>();

我收到以下错误:

 Ninject.ActivationException occurred
  HResult=-2146233088
  Message=Error activating ICategoryRepresentationMapper
No matching bindings are available, and the type is not self-bindable.
Activation path:
  1) Request for ICategoryRepresentationMapper

Suggestions:
  1) Ensure that you have defined a binding for ICategoryRepresentationMapper.
  2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
  3) Ensure you have not accidentally created more than one kernel.
  4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
  5) If you are using automatic module loading, ensure the search path and filters are correct.

编辑

如果我这样做,它会起作用,但我不想显式绑定 ICategoryRepresentationMapper。它必须是通用的,因为我会有很多映射器。

    IKernel kernel = new StandardKernel();


            Mapper.Initialize(map =>
            {
                map.ConstructServicesUsing(f => kernel.Get(f));
            });

            kernel.Bind<IMappingEngine>().ToMethod(x => Mapper.Engine);
            kernel.Bind<IConfigurationProvider>().ToMethod(x => Mapper.Engine.ConfigurationProvider);
            kernel.Bind<IConfiguration>().ToMethod(x => Mapper.Configuration);     
// This line below will actualy work but it isn't generic                 
            kernel.Bind(
              x =>
                  x.FromAssemblyContaining< ICategoryRepresentationMapper>()
                      .SelectAllClasses()
                      .InheritedFrom(typeof(IMapper<,>))
                      .BindAllInterfaces());

看来我找到了这个问题的答案。集会们看看哪里错了。

而不是这样做:

kernel.Bind(
      x =>
          x.FromAssemblyContaining(typeof(IMapper<,>))
              .SelectAllClasses()
              .InheritedFrom(typeof(IMapper<,>))
              .BindAllInterfaces());

我需要这样做并且有效:

var codeBase = Assembly.GetExecutingAssembly().CodeBase;
        var uri = new UriBuilder(codeBase);
        var path = Uri.UnescapeDataString(uri.Path);

        _kernel.Bind(
          x =>
              x.FromAssembliesInPath(Path.GetDirectoryName(path))
                  .SelectAllClasses()
                  .InheritedFrom(typeof(IMapper<,>))
                  .BindAllInterfaces());