Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Ninject在MVC 3中注入属性_C#_Asp.net Mvc 3_Ninject - Fatal编程技术网

C# 使用Ninject在MVC 3中注入属性

C# 使用Ninject在MVC 3中注入属性,c#,asp.net-mvc-3,ninject,C#,Asp.net Mvc 3,Ninject,我正在尝试将一个属性注入到我的名为UnitOfWorkAttribute的ActionFilter中。我有以下代码: [Inject] public IUnitOfWork UnitOfWork { get; set; } 在执行之前,我告诉Ninject用以下方法解决此问题: Bind<IUnitOfWork>().To<NHibernateUnitOfWork>().InThreadScope(); 这是我的混凝土: public interface INHibe

我正在尝试将一个属性注入到我的名为UnitOfWorkAttribute的ActionFilter中。我有以下代码:

[Inject]
public IUnitOfWork UnitOfWork { get; set; }
在执行之前,我告诉Ninject用以下方法解决此问题:

Bind<IUnitOfWork>().To<NHibernateUnitOfWork>().InThreadScope();
这是我的混凝土:

public interface INHibernateUnitOfWork : IUnitOfWork
{
    ISession Session { get; }
}

public class NHibernateUnitOfWork : INHibernateUnitOfWork
{
    private readonly ISessionSource sessionSource;
    private ITransaction transaction;
    private ISession session;

    private bool disposed;
    private bool begun;

    public NHibernateUnitOfWork(ISessionSource sessionSource)
    {
        this.sessionSource = sessionSource;
        Begin();
    }

    //.......
}
我正在完成//…下的接口


我做错了什么?

问题是Ninject从来没有机会在ActionFilter上“做自己的事”,这是由
FilterAttributeFilterProvider在MVC内部处理的。您需要做的是告诉MVC使用一个自定义的
FilterAttributeFilterProvider
,您可以在执行过滤器之前拦截它们。请允许我演示:

假设我有这个接口和实现:

public interface IFoo
{

}

public class Foo : IFoo
{

}
然后我有一个ActionFilter:

public class MyActionFilterAttribute : ActionFilterAttribute
{
    public MyActionFilterAttribute()
    {
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //do something with Foo
        base.OnActionExecuting(filterContext);
    }

    [Inject]
    public IFoo Foo { get; set; }
}
然后我们有一个控制器:

public class HomeController : Controller
{
    [MyActionFilter]
    public ActionResult Index()
    {
        return View();
    }
}
如果现在按原样运行,显然在MyActionFilter中Foo仍然是空的,所以让我们继续

让我们设置Ninject DependencyResolver:

public class NinjectDependencyResolver : IDependencyResolver
{
    private readonly IKernel _kernel;

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
    {
        return _kernel.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _kernel.GetAll(serviceType);
    }
}
公共类NinjectDependencyResolver:IDependencyResolver
{
私有只读IKernel_内核;
公共NinjectDependencyResolver(IKernel内核)
{
_内核=内核;
}
公共对象GetService(类型serviceType)
{
return _kernel.TryGet(serviceType);
}
公共IEnumerable GetServices(类型serviceType)
{
返回_kernel.GetAll(serviceType);
}
}
现在让我们在Global.asax中使用它:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        DependencyResolver.SetResolver(new NinjectDependencyResolver(GetKernel()));
    }

    private IKernel GetKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().To<Foo>();
        return kernel;
    }
    private IKernel GetKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().To<Foo>();
        //use our custom NinjectFilterProvider
        kernel.Bind<IFilterProvider>().To<NinjectFilterProvider>();
        return kernel;
    }
受保护的无效应用程序\u Start()
{
RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
注册地址(RouteTable.Routes);
SetResolver(新的NinjectDependencyResolver(GetKernel());
}
私有IKernel GetKernel()
{
var kernel=新的标准内核();
kernel.Bind().To();
返回内核;
}
越来越近了,但是MVC在创建操作过滤器时仍然没有办法使用Ninject内核。我们将在这里实现这一点

第一:

public class NinjectFilterProvider : FilterAttributeFilterProvider
{
    private readonly IKernel _kernel;

    public NinjectFilterProvider(IKernel kernel)
    {
        _kernel = kernel;
    }

    public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        var filters = base.GetFilters(controllerContext, actionDescriptor);

        foreach (var filter in filters)
        {

            _kernel.Inject(filter.Instance);
        }

        return filters;
    }
}
公共类NinjectFilterProvider:FilterAttributeFilterProvider
{
私有只读IKernel_内核;
公共NinjectFilterProvider(IKernel内核)
{
_内核=内核;
}
公共覆盖IEnumerable GetFilters(ControllerContext ControllerContext,ActionDescriptor ActionDescriptor)
{
var filters=base.GetFilters(controllerContext,actionDescriptor);
foreach(过滤器中的var过滤器)
{
_注入(filter.Instance);
}
回流过滤器;
}
}
这里发生的事情是,我们正在创建一个自定义FilterAttributeFilterProvider类。在OnActionExecuting方法中,在我们通过基本实现获得所有过滤器之后,我们可以调用Ninjects Inject方法,该方法将检查实例并查看它是否可以向其中注入任何内容(使用Inject属性)

最后一个难题是为我们的定制过滤器TributeTFilterProvider设置绑定:

Global.asax:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        DependencyResolver.SetResolver(new NinjectDependencyResolver(GetKernel()));
    }

    private IKernel GetKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().To<Foo>();
        return kernel;
    }
    private IKernel GetKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().To<Foo>();
        //use our custom NinjectFilterProvider
        kernel.Bind<IFilterProvider>().To<NinjectFilterProvider>();
        return kernel;
    }
private IKernel GetKernel()
{
var kernel=新的标准内核();
kernel.Bind().To();
//使用我们的定制NinjectFilterProvider
kernel.Bind().To();
返回内核;
}

现在,当MVC获取一个
IFilterProvider
(它会通过DependencyResolver自动执行此操作)它不会得到默认的
FilterAttributeFilterProvider
,而是会得到我们的自定义
NinjectFilterProvider
,因此我们的Foo实例将被填充到自定义操作筛选器中。

问题是Ninject从来没有机会在ActionFilter上“做它该做的事”,这在MVC内部由
FilterAttributeFilterProvider
处理。您需要做的是告诉MVC使用一个自定义的
FilterAttributeFilterProvider
,您可以在执行过滤器之前拦截它们。请允许我演示:

假设我有这个接口和实现:

public interface IFoo
{

}

public class Foo : IFoo
{

}
然后我有一个ActionFilter:

public class MyActionFilterAttribute : ActionFilterAttribute
{
    public MyActionFilterAttribute()
    {
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //do something with Foo
        base.OnActionExecuting(filterContext);
    }

    [Inject]
    public IFoo Foo { get; set; }
}
然后我们有一个控制器:

public class HomeController : Controller
{
    [MyActionFilter]
    public ActionResult Index()
    {
        return View();
    }
}
如果现在按原样运行,显然在MyActionFilter中Foo仍然是空的,所以让我们继续

让我们设置Ninject DependencyResolver:

public class NinjectDependencyResolver : IDependencyResolver
{
    private readonly IKernel _kernel;

    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetService(Type serviceType)
    {
        return _kernel.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _kernel.GetAll(serviceType);
    }
}
公共类NinjectDependencyResolver:IDependencyResolver
{
私有只读IKernel_内核;
公共NinjectDependencyResolver(IKernel内核)
{
_内核=内核;
}
公共对象GetService(类型serviceType)
{
return _kernel.TryGet(serviceType);
}
公共IEnumerable GetServices(类型serviceType)
{
返回_kernel.GetAll(serviceType);
}
}
现在让我们在Global.asax中使用它:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        DependencyResolver.SetResolver(new NinjectDependencyResolver(GetKernel()));
    }

    private IKernel GetKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().To<Foo>();
        return kernel;
    }
    private IKernel GetKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().To<Foo>();
        //use our custom NinjectFilterProvider
        kernel.Bind<IFilterProvider>().To<NinjectFilterProvider>();
        return kernel;
    }
受保护的无效应用程序\u Start()
{
RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
注册地址(RouteTable.Routes);
SetResolver(新的NinjectDependencyResolver(GetKernel());
}
私有IKernel GetKernel()
{
var kernel=新的标准内核();
kernel.Bind().To();
返回内核;
}
越来越近了,但是MVC在创建操作过滤器时仍然没有办法使用Ninject内核。我们将在这里实现这一点

第一:

public class NinjectFilterProvider : FilterAttributeFilterProvider
{
    private readonly IKernel _kernel;

    public NinjectFilterProvider(IKernel kernel)
    {
        _kernel = kernel;
    }

    public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        var filters = base.GetFilters(controllerContext, actionDescriptor);

        foreach (var filter in filters)
        {

            _kernel.Inject(filter.Instance);
        }

        return filters;
    }
}
公共类NinjectFilterProvider:FilterAttributeFilterProvider
{
私有只读IKernel_内核;
公共NinjectFilterProvider(IKernel内核)
{
_内核=内核;
}
公共覆盖IEnumerable GetFilters(ControllerContext ControllerContext,ActionDescriptor ActionDescriptor)
{
var filters=base.GetFilters(controllerContext,actionDescriptor);
foreach(过滤器中的var过滤器)
{
_注入(filter.Instance);
}
回流过滤器;
}
}
这里发生的事情是,我们正在创建一个自定义FilterAttributeFilterProvid