我在注册我的界面时遇到了一些问题。我有以下接口:
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,我不想要。我可以这样解决它还是必须使用硬连线版本?
你所拥有的是你的接口定义的问题。如果您将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注册也将如此。