Asp.net mvc 动作过滤器中的Ninject

Asp.net mvc 动作过滤器中的Ninject,asp.net-mvc,ninject,Asp.net Mvc,Ninject,我已经创建了一个自定义操作筛选器,并将其与Ninject的BindFilter方法绑定: public class ExtendModelAttribute : FilterAttribute {} public class ExtendModelFilter : IActionFilter { private IKernel kernel; public ExtendModelFilter(Func<IKernel> kernel) { t

我已经创建了一个自定义操作筛选器,并将其与Ninject的BindFilter方法绑定:

public class ExtendModelAttribute : FilterAttribute {}

public class ExtendModelFilter : IActionFilter
{
    private IKernel kernel;
    public ExtendModelFilter(Func<IKernel> kernel)
    {
        this.kernel = kernel;
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // TODO:
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}
我想让ExtendModel过滤器做的是确定正在使用的模型类型,然后找到正确的依赖项:

public interface IModelExtender<TModel> {
    void Extend(TModel model);
}

public class IndexModelExtender : IModelExtender<IndexModel> {
    public void Extend(IndexModel model)
    {
        // extend the model here with anything extra that is required
    }
}

您必须使用反射,因为模型类型仅在运行时已知,并且您的扩展器是通用的:

public class ExtendModelFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        object model = null;
        if (filterContext.Result is ViewResultBase)
        {
            model = ((ViewResultBase)filterContext.Result).Model;
        }
        else if (filterContext.Result is JsonResult)
        {
            model = ((JsonResult)filterContext.Result).Data;
        }
        // TODO: you could continue with the else if here to take
        // into account some other action results that have the notion of model
        // like for example some custom action results that you might have written

        if (model == null)
        {
            // we have no model => nothing to extend
            return;
        }

        var extenderType = typeof(IModelExtender<>).MakeGenericType(model.GetType());
        var extender = DependencyResolver.Current.GetService(extenderType);
        var extend = extenderType.GetMethod("Extend");
        extend.Invoke(extender, new[] { model });
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}
公共类扩展模型过滤器:IActionFilter
{
已执行ActionExecuted(ActionExecutedContext筛选器上下文)的公共无效
{
对象模型=null;
如果(filterContext.Result为ViewResultBase)
{
模型=((ViewResultBase)filterContext.Result);
}
else if(filterContext.Result为JsonResult)
{
model=((JsonResult)filterContext.Result);
}
//托多:若你们在这里拍摄的话,你们可以继续拍摄
//考虑到其他一些具有模型概念的行动结果
//例如,您可能已经编写了一些自定义操作结果
if(model==null)
{
//我们没有模型=>无需扩展
返回;
}
var extenderType=typeof(IModelExtender).MakeGenericType(model.GetType());
var extender=dependencyrolver.Current.GetService(extenderType);
var extend=extenderType.GetMethod(“extend”);
Invoke(extender,new[]{model});
}
ActionExecuting(ActionExecutingContext filterContext)上的公共无效
{
}
}

您还将注意到,我已经重构了自定义操作过滤器,以便使用当前的依赖项解析器,并使其不受对象的影响。如果您愿意,您当然可以保留
IKernel
依赖项。

您能解释一下您试图用这些做什么吗?在我看来,您似乎希望获得帮助,以获得一个非常复杂的解决方案,该解决方案可以使用Html.RenderAction()轻松解决。@RemoGloor我想做的是创建一个操作过滤器,该过滤器将填充模型上的查找列表。在上面的示例中,我的IndexModelExtender依赖于某个存储库/服务,该存储库/服务将填充SelectList的所有项目,因此我将其排除在控制器之外。@Remoglo或者我更新了我的问题,并提供了更多的细节。@Dismissile-我同意remo的意见,对于一个简单的问题来说,这似乎是一个非常复杂的解决方案。@MystereMan当我看到同一类型的锅炉铭牌代码被反复编写时,我开始考虑如何改进它。如果模型状态无效,则每个控制器操作都需要在GET操作和POST操作上填充一些查找列表。我只是想找到一种避免重复所有这些代码的方法,并开始探索这条道路。谢谢Darin。您总能找到答案。但是,此解决方案需要使用服务位置。我意识到没有太多的选择,但这就是为什么您通常在控制器中执行这项工作的原因,因为依赖项在那里被注入,而不是注入到属性代码中。
public interface IModelExtender<TModel> {
    void Extend(TModel model);
}

public class IndexModelExtender : IModelExtender<IndexModel> {
    public void Extend(IndexModel model)
    {
        // extend the model here with anything extra that is required
    }
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
    // TODO:
    // I Need to look at the filterContext Model to determine which 
    // type of IModelExtender<T> to create:
    // For Example, when [ExtendModel] is applied on the Index() method above
    // then I need it to resolve to IndexModelExtender
}
public class IndexModelExtender : IModelExtender<IndexModel>
{
    public IndexModelExtender(IFooRepository fooRepository, IBarRepository barRepository)
     {
        // ...
     }

     public void Extend(IndexModel model)
     {
         model.SelectList1 = new SelectList(fooRepository.GetFoos(), "Description", "Id");
         model.SelectList2 = new SelectList(barRepository.GetBars(), "Description", "Id");
     }
}
 public ActionResult Index()
 {
     var model = new IndexModel();
     // populate select lists here
     return View(model);
 }

 [HttpPost]
 public ActionResult Index(IndexModel model)
 {
     if(!ModelState.IsValid ) {
        // populate the same stuff here
     }
  }
public class ExtendModelFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        object model = null;
        if (filterContext.Result is ViewResultBase)
        {
            model = ((ViewResultBase)filterContext.Result).Model;
        }
        else if (filterContext.Result is JsonResult)
        {
            model = ((JsonResult)filterContext.Result).Data;
        }
        // TODO: you could continue with the else if here to take
        // into account some other action results that have the notion of model
        // like for example some custom action results that you might have written

        if (model == null)
        {
            // we have no model => nothing to extend
            return;
        }

        var extenderType = typeof(IModelExtender<>).MakeGenericType(model.GetType());
        var extender = DependencyResolver.Current.GetService(extenderType);
        var extend = extenderType.GetMethod("Extend");
        extend.Invoke(extender, new[] { model });
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
    }
}