Внедрение Autofac Dependency на параметры метода действия (ASP MVC3) - PullRequest
1 голос
/ 22 октября 2011

У меня есть следующие настройки

public interface IObject 
{ 
    string Name { get; set;}
}

public class ConcreteObject : IObject 
{
    public string Name { get; set; }
}
public ActionResult Index(IObject myObject)
{        
    return View();
}

У меня есть конкретный класс, который реализует IObject, и я использую внедрение зависимостей для привязки этого конкретного класса к интерфейсу.

Используя Autofac, у меня также есть следующие настройки

var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacWebTypesModule());
builder.RegisterSource(new ViewRegistrationSource());
builder.RegisterFilterProvider();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).InjectActionInvoker().PropertiesAutowired();
builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
builder.RegisterModelBinderProvider();
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>().WithParameter("injectActionMethodParameters", true);
builder.RegisterType<ConcreteObject>().As<IObject>().InstancePerHttpRequest();            
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

Когда я запускаю это, я получаю экземпляр конкретного класса, но любые параметры, которые обычно связаны с строкой запроса, теперь равны нулю. то есть: Home / Index? Name = test будет привязывать экземпляр, но не привязывать параметр Name. Есть ли способ гарантировать, что привязка модели все еще происходит после DI?

Ответы [ 2 ]

2 голосов
/ 24 октября 2011

Редактировать: я никогда не рекомендую делать это, вы никогда не должны вводить интерфейсы в методы действия!

Хорошо, я решил это.Я установил привязку пользовательской модели, которую я вызываю при наличии интерфейса.

public class YourModelBinderProvider : IModelBinderProvider
{    
    public IModelBinder GetBinder(Type modelType)
    {
        if (modelType.IsInterface)
        {
            return new InterfaceModelBinder();
        }
        return null;
    }
}
public class InterfaceModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        ModelBindingContext context = new ModelBindingContext(bindingContext);
        var item = DependencyResolver.Current.GetService(bindingContext.ModelType);            

        Func<object> modelAccessor = () => item;
        context.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(),
            bindingContext.ModelMetadata.ContainerType, modelAccessor, item.GetType(), bindingContext.ModelName);

        return base.BindModel(controllerContext, context);
    }
}

Тогда в моем global.asax у меня просто есть

ModelBinderProviders.BinderProviders.Add(new YourModelBinderProvider());
var builder = new ContainerBuilder();            
builder.RegisterModelBinderProvider();
builder.RegisterType<ConcreteObject>().As<IObject>();    
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
0 голосов
/ 23 октября 2011

Несмотря на то, что я не понимаю, чего вы хотите достичь с помощью внедрения метода, вы можете попробовать вызвать метод TryUpdateModel.

...