在我基于 Model 对象动态创建 ViewModel 对象的环境中,我也遇到过几次这种情况(其他Stackoverflow 帖子对此进行了很好的概述)。
我喜欢Ninject 扩展,它允许您基于接口动态创建工厂:
Bind<IMyFactory>().ToFactory();
我无法直接在Unity中找到任何类似的功能;所以我为IUnityContainer编写了自己的扩展,它允许您注册工厂,这些工厂将基于现有对象的数据创建新对象,本质上是从一种类型层次结构映射到不同的类型层次结构:UnityMappingFactory@GitHub
出于简单和可读性的目标,我最终得到了一个扩展,它允许您直接指定映射而无需声明单个工厂类或接口(实时节省)。您只需在正常引导过程中注册类的位置添加映射...
//make sure to register the output...
container.RegisterType<IImageWidgetViewModel, ImageWidgetViewModel>();
container.RegisterType<ITextWidgetViewModel, TextWidgetViewModel>();
//define the mapping between different class hierarchies...
container.RegisterFactory<IWidget, IWidgetViewModel>()
.AddMap<IImageWidget, IImageWidgetViewModel>()
.AddMap<ITextWidget, ITextWidgetViewModel>();
然后你只需在 CI 的构造函数中声明映射工厂接口并使用它的Create()方法......
public ImageWidgetViewModel(IImageWidget widget, IAnotherDependency d) { }
public TextWidgetViewModel(ITextWidget widget) { }
public ContainerViewModel(object data, IFactory<IWidget, IWidgetViewModel> factory)
{
IList<IWidgetViewModel> children = new List<IWidgetViewModel>();
foreach (IWidget w in data.Widgets)
children.Add(factory.Create(w));
}
作为额外的奖励,映射类的构造函数中的任何其他依赖项也将在对象创建期间得到解决。
显然,这并不能解决所有问题,但到目前为止它对我的帮助很好,所以我认为我应该分享它。在 GitHub 上的项目站点上有更多文档。