Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.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/1/php/281.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# DI-创建服务对象_C#_Asp.net Mvc 4_Ninject - Fatal编程技术网

C# DI-创建服务对象

C# DI-创建服务对象,c#,asp.net-mvc-4,ninject,C#,Asp.net Mvc 4,Ninject,[注意:我的NinjectDependencyResolver类位于此问题的底部。] 设置: 在ASP.NETMVC4应用程序中,我有使用服务的控制器 每个服务都有一个IUnitOfWork接口作为构造函数参数。例如: public ClientService(IUnitOfWork uow){ //... } 在Global.asax.cs类中注册一个适当编写的NinjectDependencyResolver:IDependencyResolver类,可以正确实例化这些服务并使所有工作正常

[注意:我的NinjectDependencyResolver类位于此问题的底部。]

设置: 在ASP.NETMVC4应用程序中,我有使用服务的控制器

每个服务都有一个IUnitOfWork接口作为构造函数参数。例如:

public ClientService(IUnitOfWork uow){ //... }
在Global.asax.cs类中注册一个适当编写的
NinjectDependencyResolver:IDependencyResolver
类,可以正确实例化这些服务并使所有工作正常。到目前为止,一切顺利

但是,在某些情况下,服务需要在其他一些代码中实例化,例如在属性中。例如:

namespace MyApp.Domain.Attributes
{
    public class AuthorizeUnprocessedOnlyAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool isUnprocessed = false;

            string usuario = string.Empty;
            if (httpContext.User.Identity.IsAuthenticated)
            {
                // THIS IS THE LINE WHERE DI IS NEEDED!!
                ClientService service = new ClientService();
                usuario = httpContext.User.Identity.Name;
                isUnprocessed = service.IsUnprocessed(usuario);
            }

            return isUnprocessed;
        }
    }
}
我的问题是线路:

ClientService service = new ClientService();
我必须为ClientService提供一个无参数构造函数,如下所示:

public ClientService() : this (new UnitOfWork()) {}
这似乎完全是反DI的

这样做的原因是我不确定如何在属性代码中注入依赖项。控制器是由ControllerFactory实例化的,因此我在不知道这一点的情况下就完成了

我对Ninject或IDependencyResolver了解不够

问题1: 那么,我怎样才能超越我的
“无知模式”

我应该按照以下方式获取ClientService对象:

NinjectDependencyResolver ndr = new NinjectDependencyResolver();
IUnitOfWorkMR uow = ndr.Kernel.Get<IUnitOfWorkMR>();
IClientService service = new ClientService(uow);
NinjectDependencyResolver ndr=新的NinjectDependencyResolver();
IUnitOfWorkMR uow=ndr.Kernel.Get();
IClientService服务=新客户端服务(uow);
即使第一个问题的答案是“是”,我也不太高兴:

我仍然需要实例化ClientService的实例,因此现在我必须将IClientService接口绑定到NinjectDependencyResolver类中正确构造的ClientService实例

这我不知道怎么做,所以这是我的第二个问题:

问题2: 如何通过菊花链将IUnitoWork构造参数的依赖项注入连接起来,以正确实例化ClientService?(请参见下面我的注释-我注释了它,因为它对我来说根本没有意义-我不应该创建UnitOfWork的新实例,是吗?)

NinjectDependencyResolver类:
名称空间MyApp.Domain.Infrastructure
{
公共类NinjectDependencyResolver:IDependencyResolver
{
私有IKernel内核;
公共NinjectDependencyResolver()
{
内核=新的标准内核();
AddBindings();
}
公共对象GetService(类型serviceType)
{
返回kernel.TryGet(serviceType);
}
公共IEnumerable GetServices(类型serviceType)
{
返回kernel.GetAll(serviceType);
} 
公共IBindingToSyntax绑定()
{
返回kernel.Bind();
}
公共IKernel核
{
获取{返回内核;}
}
私有void AddBindings()
{
kernel.Bind().To().InRequestScope();
//kernel.Bind().To().WithConstructorArgument(“uow”,newUnitOfWork());
}
}
}
注: 我已经更正了WithConstructorArgument中的错误(缺少参数名)

编辑:

在测试中,不可思议的事情发生了:问题1中的代码可以工作。至于问题2,NinjectDependedEncyResolver类中的以下更改突然释放了一个可用的应用程序(这些事情确实是罕见的乐趣):

kernel.Bind().To().InRequestScope();
kernel.Bind().To().InRequestScope();
也就是说,我删除了WithConstructorArgument调用。Ninject大概有一个UnitOfWork的工作实例,它使用它来实例化我的服务。所以,不再有无参数构造函数


但是这是RWTDI(正确的方法)吗?

是的,这是配置绑定的正确方法。这就是DI容器的全部要点,它根据构造函数的参数和配置确定要注入什么

然而,我发现你的NinjectDependcyResolver很奇怪。为什么不直接使用Ninject.MVC3呢?(它也适用于MVC4)。这将自动为MVC设置DependencyResolver,您将在App_Start\njectWebCommon.cs中配置映射

对于属性,正确的方法是使用随Ninject.MVC3自动安装的BindFilter扩展。您可以这样配置它:

kernel.BindFilter<MyAuthorization>(FilterScope.Action, 0)
    .WhenActionMethodHas<MyAuthorization>();
var x = DependencyResolver.Current.GetService<MyType>(); 
kernel.BindFilter(FilterScope.Action,0)
.WhenActionMethodHas();
然后Ninject将自动处理注入其中的任何配置对象

这就消除了从属性内部调用GetService的需要(这总是一种代码味道),并使所有内容都能协同工作

至少,使用Ninject.MVC3来设置您的MVC应用程序,然后在过滤器中,如果您真的想调用GetService,那么使用MVC DependencyResolver(Ninject.MVC自动向其注册)并执行以下操作:

kernel.BindFilter<MyAuthorization>(FilterScope.Action, 0)
    .WhenActionMethodHas<MyAuthorization>();
var x = DependencyResolver.Current.GetService<MyType>(); 
var x=DependencyResolver.Current.GetService();

但同样,您应该真正使用BindFilter语法。

事实上,问题1中的代码似乎运行良好,有效的方法是按照NinjectDependencyResolver类中的要求绑定每个服务或类,而不指定UnitOfWork参数,大概是因为Ninject已经实例化并处理了这个问题。细节上仍然有点模糊,但是,嘿,什么有效,为什么要改变它?我在问题中添加了一个编辑。我在跟踪史蒂夫·桑德森和亚当·弗里曼。我将按照您的建议,切换到Ninject.MVC3。我们一定会看看BindFilter语法。非常感谢您的详细答复。