注册和解析通用对象

问题描述 投票:0回答:1

我在注册我的界面时遇到了一些问题。我有以下接口:

public interface IMapper<Q, T> { /* Mapper Helper Methods */ }
public interface ISourceObject { /* Properties */ }
public interface ITargetObject { /* Properties */ }

实施是:

public class GenericMapper<Q, T> : IMapper<Q,T> { /* Mapper Helper Methods */ }
public class SourceObject : ISourceObject { /* Properties */ }
public class TargetObject : ITargetObject { /* Properties */ }

在我的Autofac模块中,我想将其注册如下:

builder.RegisterType<GenericMapper<SourceObject, TargetObject>>().As<IMapper<ISourceObject, ITargetObject>>();

并通过以下方式解决:

Container.Resolve<IMapper<ISourceObject, ITargetObject>>();

自动映射配置文件配置为:

CreateMap<ISourceObject, ITargetObject>()
                    // ForMember Mappings
.ForAllMembers(o => o.Condition((src, dest, value) => value != null));

当我开始我的Unittest时,它崩溃了以下Stacktrace:

at Autofac.Builder.RegistrationBuilder.CreateRegistration(Guid id, RegistrationData data, IInstanceActivator activator, IEnumerable`1 services, IComponentRegistration target)
   at Autofac.Builder.RegistrationBuilder.CreateRegistration[TLimit,TActivatorData,TSingleRegistrationStyle](IRegistrationBuilder`3 builder)
   at Autofac.Builder.RegistrationBuilder.RegisterSingleComponent[TLimit,TActivatorData,TSingleRegistrationStyle](IComponentRegistry cr, IRegistrationBuilder`3 builder)
   at Autofac.RegistrationExtensions.<>c__DisplayClass3_0`1.<RegisterType>b__0(IComponentRegistry cr)
   at Autofac.ContainerBuilder.Build(IComponentRegistry componentRegistry, Boolean excludeDefaultModules)
   at Autofac.ContainerBuilder.Build(ContainerBuildOptions options)

System.ArgumentException: 
    System.ArgumentException: The type 'App.Test.Models.GenericMapper`2[App.Test.Models.SourceObject,App.Test.Models.TargetObject]' is not assignable 
    to service 'App.Test.Models.IMapper`2[[App.Test.Models.ISourceObject, App.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],
    [App.Test.Models.ITargetObject, App.Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'..

我有什么不对吗?当我注册实现时,解决方案没有问题。但它将是实施的Hardwired,我不想要。我可以这样解决它还是必须使用硬连线版本?

automapper autofac
1个回答
0
投票

你所拥有的是你的接口定义的问题。如果您将Autofac完全从混合中拉出来并手动测试,您可以看到证据:

[Fact]
public void TypesAreCompatible()
{
    var init = new GenericMapper<SourceObject, TargetObject>();
    var cast = (IMapper<ISourceObject, ITargetObject>)init;
    Assert.Same(init, cast);
}

这将在以var cast开头的行上失败并给出异常:

System.InvalidCastException : Unable to cast object of type 'GenericMapper`2[SourceObject,TargetObject]' to type 'IMapper`2[ISourceObject,ITargetObject]'.

原因是your IMapper interface is not covariant.简单来说,这意味着你不能把更多的派生类型作为Q或T,并让它“神奇地工作”。必须准确。

更新你的界面告诉C#,通过将out放在类型参数前面,可以使用协变类型。

public interface IMapper<out Q, out T> { }

一旦你这样做,我上面的测试将起作用...... Autofac注册也将如此。

© www.soinside.com 2019 - 2024. All rights reserved.