例如,在我的项目中,我有一个自定义活页夹,它可以执行以下操作(我将它与 ViewModel 一起使用,如下所示):
public interface IEntityResolver
{
object Find(string id);
}
public class PrimaryKeyResolver<T> where T: Entity
{
public PrimaryKeyResolver(IRepository<T> repository) {}
public object Find(string id)
{
return repository.Get(new Guid(id));
}
}
public class NameResolver<T> where T: NamedEntity
{
public NameResolver(IRepository<T> repository) {}
public object Find(string id)
{
return repository.Find(new { Name = id });
}
}
public class MyBinder: IModelBinder
{
public override object BindModel()
{
var id = ... //get id from context
var resolverType = typeof(IResolver<>).MakeGenericInterface(typeof(bindingContext.ModelType));
var resolver = ServiceLocator.Current.GetInstance(resolverType);
return resolver.Find(id);
}
}
现在,有什么好处以及为什么它与 IoC 有关?这有助于我使我的模型绑定器不受实体解析问题的影响,同时保留关注点分离。id 是什么意思以及我们如何获得实体被委托给解析器。这有助于为任何实体重用相同的 IModelBinder。如果(如上所示)我想按名称而不是 id 搜索,我唯一需要做的就是提供模型解析器。
此处的 IoC(我使用服务定位器,但无论如何)有助于找到合适的解析器并实例化它。请注意,解析器接受 IRepository,它是 IoC 容器自动传递的。
关于您的具体问题,当然我们应该将 IoC与IModelBinder 一起使用,而不是没有 - 但您可能也可以使用 IoC 来实例化 IModelBinder - 这将避免使用 ServiceLocator;但我不知道如何拦截创建活页夹的 MVC,坦率地说,我不在乎,因为我对 Locator 很满意。
至于 KiGG,我通常建议不要依赖诸如 NerdDinner 或 Oxite 之类的示例项目(不能告诉任何关于 KiGG 的内容),就好像它们是“好的设计”参考一样——据我所知,它们通常展示技术方面(即功能),不是很好的设计。