动作方法参数的Autofac依赖注入(ASP MVC3)

时间:2011-10-22 12:21:47

标签: c# asp.net-mvc-3 autofac

我有以下设置

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));

当我运行它时,我得到了具体类的实例,但是通常从查询字符串绑定的任何参数现在都是null。 ie:Home / Index?Name = test将绑定一个实例,但不绑定参数Name。有没有办法确保在DI之后仍然发生模型绑定?

2 个答案:

答案 0 :(得分:2)

编辑:我不建议这样做,你不应该将接口注入动作方法!。

好的,我解决了这个问题。我设置了一个自定义模型绑定器,我在界面存在时调用它。

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));

答案 1 :(得分:0)

尽管我不明白你想用方法注入实现什么,但你可以尝试调用TryUpdateModel方法。