动作方法参数的自动依赖注入(ASP MVC3)
本文关键字:ASP MVC3 注入 方法 参数 依赖 | 更新日期: 2023-09-27 18:12:18
设置如下
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));
当我运行这个时,我得到了一个具体类的实例,但是通常从querystring绑定的任何参数现在都是空的。即:家庭/索引?Name=test将绑定实例,但不绑定参数Name。是否有一种方法可以确保在DI之后仍然发生建模绑定?
编辑:我不建议这样做,你不应该把接口注入到动作方法中!
好,我解决了这个问题。我设置了一个自定义模型绑定器,当存在接口时调用它。
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);
}
}
然后在我的全局。如果我有
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));
尽管我不明白你想用方法注入实现什么,你可以尝试调用TryUpdateModel
方法。