Внедрение пользовательских связывателей моделей со структурной картой 3
Я нашел несколько руководств по внедрению пользовательских связывателей моделей в ASP.NET MVC
использование проекта StructureMap
и последовал за этим учебником: http://benfoster.io/blog/model-binder-dependency-injection-structuremap
Я установил StructureMap.MVC5
пакет. И добавили привязку типов внутри реестра по умолчанию:
public class DefaultRegistry : Registry {
public DefaultRegistry() {
Scan(scan => {
scan.Assembly(System.Reflection.Assembly.GetExecutingAssembly());
scan.WithDefaultConventions();
scan.With(new ControllerConvention());
});
For(typeof(IRepository<>)).Use(typeof(MongoDbRepository<>));
var dictionary = new ModelBinderMappingDictionary();
dictionary.Add<Car, CarModelBinder>();
For<ModelBinderMappingDictionary>().Use(dictionary);
For<IModelBinderProvider>().Use<StructureMapModelBinderProvider>();
}
}
public class StructureMapModelBinderProvider : IModelBinderProvider {
private readonly IContainer container;
public StructureMapModelBinderProvider(IContainer container) {
this.container = container;
}
public IModelBinder GetBinder(Type modelType) {
var mappings = container.GetInstance<ModelBinderMappingDictionary>();
if(mappings != null && mappings.ContainsKey(modelType))
return container.GetInstance(mappings[modelType]) as IModelBinder;
return null;
}
}
Теперь я получаю NullReferenceException
который указывает на линию:
var mappings = container.GetInstance<ModelBinderMappingDictionary>();
И эти внутренние исключения текста:
StructureMap.SessionCache.GetDefault (Тип pluginType, IPipelineGraph pipelineGraph) в c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\SessionCache.cs:43 StructureMap.Container.GetInstance(Тип pluginType) в c: \ 96a \ 9d8a \ 896 \ \ dcd3d \ Buc \ 9aD3D \ \src\StructureMap\Container.cs:331 StructureMap.Container.GetInstance() в c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\Container.cs:201 my_project_name.StructureMapModelBinderProvider.GetBinder \ в типовой модели: тип: unicorn\unicorn.web\ Infrastructure\model_binding\StructuremapModelBinderProvider.cs:15 System.Web.Mvc.ModelBinderProviderCollection.GetBinder(тип modelType) +57 System.Web.Mvc.ModelBinderDictionary.GetBinder(тип modelType, системный перепад назад + IMB) Web.Mvc.ModelBinderDictionary.GetBinder (Тип modelType, Boolean fallbackToDefault) +71 и так далее...
Что не так с этим кодом?
2 ответа
Ладно, я понял!
Я пытался использовать другой тип жизненного цикла для StructureMapModelBinderProvider
:
public class ModelBindingRegistry : Registry {
public ModelBindingRegistry() {
Scan(scan => {
scan.TheCallingAssembly();
});
var dictionary = new ModelBinderMappingDictionary();
dictionary.Add<Car, CarModelBinder>();
For<ModelBinderMappingDictionary>().Use(dictionary);
For<IModelBinderProvider>().Singleton().Use<StructureMapModelBinderProvider>();
}
}
С Singleton
все работает! Не уверен, что Singleton
сфера здесь подходит?
Похоже, вы пытаетесь зарегистрировать ModelBinderMappingDictionary в качестве значения для повторного запуска из метода Add, который является недействительным. Попробуйте это (DefaultRegistry):
var modelBinderMappingDictionary = new ModelBinderMappingDictionary();
modelBinderMappingDictionary.Add<Car, CarModelBinder>();
For<ModelBinderMappingDictionary>().Use(modelBinderMappingDictionary);