Внедрение пользовательских связывателей моделей со структурной картой 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);
Другие вопросы по тегам