DryIoc 和 ExpressMapper
DryIoc and ExpressMapper
我正在使用 DryIoc 和 ExpressMapper。
我将 ExpressMapper 包装在另一个 class 中,在某些时候它应该用于映射到具有参数化构造函数的类型。实际上是当我将视图模型映射到业务模型时。该参数是存储库的实例 class.
使用 TDD,我的 Mapper class 像这样结束(注意构造函数接受 Func)。
public class Mapper<T1, T2> : IMapper<T1, T2>
{
private readonly MappingServiceProvider _mapper;
public Mapper()
{
_mapper = new MappingServiceProvider();
_mapper.Register<T1, T2>();
}
public Mapper(Func<T2> func)
{
_mapper = new MappingServiceProvider();
_mapper.Register<T1, T2>().Instantiate((t1) => func());
}
public T2 Map(T1 t)
{
return _mapper.Map<T1, T2>(t);
}
}
因此我尝试像这样使用 Ioc :
Func<IActivitiesModel>factoryActivitiesModel = () => container.Resolve<IActivitiesModel>();
container.Register(Made.Of(() => factoryActivitiesModel));
// () => new ActivitiesModel(container.Resolve<IActivityRepository>(IfUnresolved.Throw)
container.Register<IMapper<ActivitiesViewModel, IActivitiesModel>, Mapper<ActivitiesViewModel, IActivitiesModel>>(Reuse.Singleton, Made.Of(
() => new Mapper<ActivitiesViewModel, IActivitiesModel>(Arg.Of<Func<IActivitiesModel>>())
));
但是没有。
Unable to use null factory object with factory method ActivitiesMVC.Ioc.<>c__DisplayClass4_0::System.Func`1[ActivitiesLogic.Models.IActivitiesModel] factoryActivitiesModel when resolving: Func<ActivitiesLogic.Models.IActivitiesModel>.
无论如何,后来我尝试了不同的方法,但 none 似乎有效。
我想避免将容器存储为静态单例并让映射器依赖它(我希望映射器保持 Ioc 不可知)。
如何实现?
EDIt:当前解决方案(静态单例错误)
public class Ioc
{
public class Factory<T> : IFactory<T>
{
public T Create()
{
return Container.Resolve<T>();
}
}
private static Lazy<Container> _container;
public static Container Container => _container.Value;
static Ioc()
{
_container = new Lazy<Container>(GetContainer);
}
static private Container GetContainer()
{
var container = new Container(rules => rules
//.WithoutThrowOnRegisteringDisposableTransient()
.WithTrackingDisposableTransients());
container.Register(Made.Of(() => new ActivityController(Arg.Of<IMapper<ActivitiesViewModel, IActivitiesModel>>())));
container.Register<ILabContext, LabContext>(new SingletonReuse());
container.Register<IActivityRepository, ActivityRepository>(new SingletonReuse());
container.Register<IActivitiesModel>(made: Made.Of(() => new ActivitiesModel(Arg.Of<IActivityRepository>())));
container.Register(typeof(IFactory<>), typeof(Factory<>), new SingletonReuse());
container.Register<IMapper<ActivitiesViewModel, IActivitiesModel>, Mapper<ActivitiesViewModel, IActivitiesModel>>(Reuse.Singleton, Made.Of(
() => new Mapper<ActivitiesViewModel, IActivitiesModel>(Arg.Of<IFactory<IActivitiesModel>>())
));
container.Register<IMapper<ActivitiesModel, ActivitiesEntity>, Mapper<ActivitiesModel, ActivitiesEntity>>(new SingletonReuse(), Made.Of(
() => new Mapper<ActivitiesModel, ActivitiesEntity>()
));
return container;
;
}
}
首先,我对 ExpressMapper 不熟悉,所以将尝试仅根据您的示例代码提供帮助。
据我了解,您想注册活动模型、存储库、vm 等,以及依赖于 Func 依赖项的 IMapper / Mapper 实现。另一个细节是 mapper 有两个构造函数,这就是为什么您可能尝试使用 Made.Of.
但是 Made.Of 适用于 Expression>,不适用于 Func 委托。我相信这就是例外的原因。
试试这个设置:
container.Register(typeof(IMapper<,>), typeof(Mapper<,>), Reuse.Singleton,
// will select second constructor with Func parameter
made: FactoryMethod.ConstructorWithResolvableArguments);
// normal model registrations, no need to use Made.Of
// if implementations have single constructor,
// othetwise try use the same made as for Mapper.
container.Register<IActivitiesModel, ActivitiesModel>();
// ... the same way register repository, vm, etc.
如果您的代码中存在多个构造函数的情况很常见(可能是 ExpressMapper 要求有一个默认构造函数?)那么您可以为每个容器全局配置自动构造函数选择:
container = new Container(rules => rules
.With(FactoryMethod.ConstructorWithResolvableArguments));
我正在使用 DryIoc 和 ExpressMapper。
我将 ExpressMapper 包装在另一个 class 中,在某些时候它应该用于映射到具有参数化构造函数的类型。实际上是当我将视图模型映射到业务模型时。该参数是存储库的实例 class.
使用 TDD,我的 Mapper class 像这样结束(注意构造函数接受 Func)。
public class Mapper<T1, T2> : IMapper<T1, T2>
{
private readonly MappingServiceProvider _mapper;
public Mapper()
{
_mapper = new MappingServiceProvider();
_mapper.Register<T1, T2>();
}
public Mapper(Func<T2> func)
{
_mapper = new MappingServiceProvider();
_mapper.Register<T1, T2>().Instantiate((t1) => func());
}
public T2 Map(T1 t)
{
return _mapper.Map<T1, T2>(t);
}
}
因此我尝试像这样使用 Ioc :
Func<IActivitiesModel>factoryActivitiesModel = () => container.Resolve<IActivitiesModel>();
container.Register(Made.Of(() => factoryActivitiesModel));
// () => new ActivitiesModel(container.Resolve<IActivityRepository>(IfUnresolved.Throw)
container.Register<IMapper<ActivitiesViewModel, IActivitiesModel>, Mapper<ActivitiesViewModel, IActivitiesModel>>(Reuse.Singleton, Made.Of(
() => new Mapper<ActivitiesViewModel, IActivitiesModel>(Arg.Of<Func<IActivitiesModel>>())
));
但是没有。
Unable to use null factory object with factory method ActivitiesMVC.Ioc.<>c__DisplayClass4_0::System.Func`1[ActivitiesLogic.Models.IActivitiesModel] factoryActivitiesModel when resolving: Func<ActivitiesLogic.Models.IActivitiesModel>.
无论如何,后来我尝试了不同的方法,但 none 似乎有效。
我想避免将容器存储为静态单例并让映射器依赖它(我希望映射器保持 Ioc 不可知)。
如何实现?
EDIt:当前解决方案(静态单例错误)
public class Ioc
{
public class Factory<T> : IFactory<T>
{
public T Create()
{
return Container.Resolve<T>();
}
}
private static Lazy<Container> _container;
public static Container Container => _container.Value;
static Ioc()
{
_container = new Lazy<Container>(GetContainer);
}
static private Container GetContainer()
{
var container = new Container(rules => rules
//.WithoutThrowOnRegisteringDisposableTransient()
.WithTrackingDisposableTransients());
container.Register(Made.Of(() => new ActivityController(Arg.Of<IMapper<ActivitiesViewModel, IActivitiesModel>>())));
container.Register<ILabContext, LabContext>(new SingletonReuse());
container.Register<IActivityRepository, ActivityRepository>(new SingletonReuse());
container.Register<IActivitiesModel>(made: Made.Of(() => new ActivitiesModel(Arg.Of<IActivityRepository>())));
container.Register(typeof(IFactory<>), typeof(Factory<>), new SingletonReuse());
container.Register<IMapper<ActivitiesViewModel, IActivitiesModel>, Mapper<ActivitiesViewModel, IActivitiesModel>>(Reuse.Singleton, Made.Of(
() => new Mapper<ActivitiesViewModel, IActivitiesModel>(Arg.Of<IFactory<IActivitiesModel>>())
));
container.Register<IMapper<ActivitiesModel, ActivitiesEntity>, Mapper<ActivitiesModel, ActivitiesEntity>>(new SingletonReuse(), Made.Of(
() => new Mapper<ActivitiesModel, ActivitiesEntity>()
));
return container;
;
}
}
首先,我对 ExpressMapper 不熟悉,所以将尝试仅根据您的示例代码提供帮助。
据我了解,您想注册活动模型、存储库、vm 等,以及依赖于 Func 依赖项的 IMapper / Mapper 实现。另一个细节是 mapper 有两个构造函数,这就是为什么您可能尝试使用 Made.Of.
但是 Made.Of 适用于 Expression>,不适用于 Func 委托。我相信这就是例外的原因。
试试这个设置:
container.Register(typeof(IMapper<,>), typeof(Mapper<,>), Reuse.Singleton,
// will select second constructor with Func parameter
made: FactoryMethod.ConstructorWithResolvableArguments);
// normal model registrations, no need to use Made.Of
// if implementations have single constructor,
// othetwise try use the same made as for Mapper.
container.Register<IActivitiesModel, ActivitiesModel>();
// ... the same way register repository, vm, etc.
如果您的代码中存在多个构造函数的情况很常见(可能是 ExpressMapper 要求有一个默认构造函数?)那么您可以为每个容器全局配置自动构造函数选择:
container = new Container(rules => rules
.With(FactoryMethod.ConstructorWithResolvableArguments));