Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.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# 如何在非控制器类中使用Unity MVC 4添加依赖项注入(DI)_C#_Asp.net Mvc_Dependency Injection_Unity Container - Fatal编程技术网

C# 如何在非控制器类中使用Unity MVC 4添加依赖项注入(DI)

C# 如何在非控制器类中使用Unity MVC 4添加依赖项注入(DI),c#,asp.net-mvc,dependency-injection,unity-container,C#,Asp.net Mvc,Dependency Injection,Unity Container,因此,我使用Unity MVC-4实现依赖注入,它对我的控制器类非常有效,但只要我尝试注入我的非控制器类,我就会得到NullReferenceException,我可以看到注入的对象没有被框架初始化。我将为您提供我正在使用的相应类: 控制器等级(DI工程): 如果我在非控制器方法中执行相同的操作(DI在这里不起作用),我会得到一个NullReferenceException: public inteface IMyLogic { string GetMyString(); } publ

因此,我使用Unity MVC-4实现依赖注入,它对我的
控制器
类非常有效,但只要我尝试注入我的非控制器类,我就会得到
NullReferenceException
,我可以看到注入的对象没有被框架初始化。我将为您提供我正在使用的相应类:

控制器
等级(DI工程):

如果我在非控制器方法中执行相同的操作(DI在这里不起作用),我会得到一个
NullReferenceException

public inteface IMyLogic
{
    string GetMyString();
}

public class MyLogic: IMyLogic
{
    IMyService _myService;

    #region CTOR
    public MyLogic(IMyService myService)
    {
        _myService = myService;
    }
    #endregion
    
    public string GetMyString()
    {
        string mystring=string.Empty;
        
        try
        {
            mystring = _myService.GetMyStringFromDLL();  //Getting NullReferenceException here
        }
        catch (Exception ex)
        {
            StringBuilder str = new StringBuilder();
            str.AppendLine("Exception in method GetMyString, Error msg: " + ex.Message);
            WriteLog(sb);
        }
        return mystring;
    }
}
我的
BootStrapper.cs
类看起来像:

public static class Bootstrapper
{

    public static IUnityContainer Initialise()
    {
      var container = BuildUnityContainer();
        container.RegisterType<IMyService , MyService>();
        container.RegisterType<IMyLogic, MyLogic>(new HierarchicalLifetimeManager());
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

      return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
      var container = new UnityContainer();  
      RegisterTypes(container);
      return container;
    }

    public static void RegisterTypes(IUnityContainer container)
    {

    }

}
如何在
MyLogic
类中注入
IMyService

使用属性告诉Unity
MyLogic
类依赖于要注入构造函数中的对象:

[InjectionConstructor]
public MyLogic(IMyService myService)
{
   _myService = myService;
}
实际上,当注入的类包含多个构造函数时,建议使用
[InjectionConstructor]
。因此,该属性用于解决歧义消除问题。这只是我的假设,
Unity
无法解析所需类型,因为问题代码不包含代码的所有部分。但是在测试代码中,不需要
[InjectionConstructor]
属性,因为只声明了一个构造函数

这里是测试代码

IMyService
接口定义:

public interface IMyService
{
    string GetMyStringFromDLL();
}
public interface IMyLogic
{
    string GetMyString();
}
ILogic
接口定义:

public interface IMyService
{
    string GetMyStringFromDLL();
}
public interface IMyLogic
{
    string GetMyString();
}
MyLogic
实现:

public class MyLogic : IMyLogic
{
    IMyService _myService;
       
    public MyLogic(IMyService myService)
    {
        _myService = myService;
    }
        
    public string GetMyString()
    {
        var mystring = string.Empty;
        try
        {
            mystring = "MyLogic.GetMyString() -> " + _myService.GetMyStringFromDLL();
        }
        catch (Exception ex)
        {                
            System.Diagnostics.Debug.WriteLine("Exception in method MyLogic.GetMyString(): " + ex.Message); 
        }
        return mystring;
    }
}
public class MyService : IMyService
{
    public string GetMyStringFromDLL()
    {
        return "MyService.GetMyStringFromDLL() is called.";
    }
}
public class HomeController : Controller
{
    private readonly IMyService _myService;
    private readonly IMyLogic _myLogic;

    #region CTOR
    public HomeController(IMyService myService, IMyLogic myLogic)
    {
        _myService = myService;
        _myLogic = myLogic;
    }
    #endregion

    public ActionResult Index()
    {
        // Obtaining string directly from the IMyService
        var sService = _myService.GetMyStringFromDLL();

        // Obtaining string through the IMyLogic
        var sLogic = _myLogic.GetMyString();

        return View(new List<string>() { sService, sLogic} );
    }
}
MyService
实现:

public class MyLogic : IMyLogic
{
    IMyService _myService;
       
    public MyLogic(IMyService myService)
    {
        _myService = myService;
    }
        
    public string GetMyString()
    {
        var mystring = string.Empty;
        try
        {
            mystring = "MyLogic.GetMyString() -> " + _myService.GetMyStringFromDLL();
        }
        catch (Exception ex)
        {                
            System.Diagnostics.Debug.WriteLine("Exception in method MyLogic.GetMyString(): " + ex.Message); 
        }
        return mystring;
    }
}
public class MyService : IMyService
{
    public string GetMyStringFromDLL()
    {
        return "MyService.GetMyStringFromDLL() is called.";
    }
}
public class HomeController : Controller
{
    private readonly IMyService _myService;
    private readonly IMyLogic _myLogic;

    #region CTOR
    public HomeController(IMyService myService, IMyLogic myLogic)
    {
        _myService = myService;
        _myLogic = myLogic;
    }
    #endregion

    public ActionResult Index()
    {
        // Obtaining string directly from the IMyService
        var sService = _myService.GetMyStringFromDLL();

        // Obtaining string through the IMyLogic
        var sLogic = _myLogic.GetMyString();

        return View(new List<string>() { sService, sLogic} );
    }
}
引导程序
初始化:

public static class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = new UnityContainer();
        container.RegisterType<IMyService, MyService>();            
        container.RegisterType<IMyLogic, MyLogic>(new HierarchicalLifetimeManager()); 
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        return container;
    }
}
最后,当执行
Home
控制器的默认操作方法时,显示以下两行:

MyService.GetMyStringFromDLL() is called.
MyLogic.GetMyString() -> MyService.GetMyStringFromDLL() is called.

自从我上次在NopCommerce V1.90上做了一些工作之后,我就没有使用Unity,但是我确实记得,如果在实现IUnityResolver的实例上使用Resolve,那么在容器中注册的任何内容都会返回


因此,基本上,您注册了IMyService,但您还必须注册IMyLogic-然后,您不必执行“var logic=new MyLogic();”,而是执行“var logic=resolver.Resolve(typeof(IMyLogic));”,然后您的注入参数将根据依赖项注入器进行解析(或者,如果缺少这些参数,您将得到正确的错误).

这是否回答了您的问题@拉胡尔·夏尔马:你的
Unity.Mvc4
运行时版本是什么?请公开您的
IMyService
MyService
定义。因为我将您的代码放在我的应用程序中(也使用Framework v4.5),并且它正在工作。@Rahul Sharma:根据您的问题描述,
MyLogic
类中的
\u myService
字段为
null
(未初始化-将断点放在调试器中并检查)。这意味着在执行向容器注册类型
MyLogic
映射之前,将调用
MyLogic.GetMyString()
方法。所以,首先,有一些代码和这个问题相关,但在本文中并没有公开。第二,尝试移动两行
container.RegisterType();容器。RegisterType@Jackdaw正如您在my Global.asax中看到的,
Bootstrapper.Initialise()以确保容器与my service正确映射。我也尝试了你的其他建议,并将我的服务移动到
Bootstrapper.BuildUnityContainer()
方法,但不幸的是结果是一样的。我也犯了同样的错误。如何检查Unity.Mvc4运行时版本?另外,公开我的
IMyService
也不会有任何效果,因为生成错误的原因是
\u myService
对象被接收为空。我仔细检查了MyService的逻辑,所有的东西都在那里。你是如何实例化MyLogic的?另外,除非您特别需要层次结构CallifeTimeManager,否则我建议使用TransientLifetimeManager、PerResolveLifetimeManager或PerThreadLifetimeManager。使用HierarchyAllifetimeManager,子容器并不总是与父容器相同。感谢您提供的详细答案,我非常感谢您的努力,但不幸的是,在我的情况下,它不起作用,这可能是因为我正在使用的统一版或其他一些我无法确定的东西。我尝试了你和其他人建议的所有组合,但根本不起作用。我通过在调用
GetMyStringFromDLL
之前添加以下内容来解决此问题:
var-sService=dependencysolver.Current.GetService()。我甚至尝试了
[InjectionConstructor]
属性,因为我的类有多个构造函数,但它仍然不起作用。你能在非控制器类中尝试上面的练习,看看它是否起作用吗?基本上,我的意思是尝试注入
\u myService
,然后调用
var-sService=\u myService.GetMyStringFromDLL()
在一个非控制器类中,它不是从
控制器
类继承的。@Rahul Sharma:但这正是
逻辑
类中的。
逻辑
类不继承自
控制器
,它具有
var mystring=\u myService.GetMyStringFromDLL()呼叫。我误解了什么吗?哦,是的,你是对的。我坚信你的解决方案足够了,但在我的情况下,它不起作用。我会把赏金给你的。再次感谢。如果您能告诉我您用于
Unity
MVC
的版本,那就太好了。@Rahul Sharma:我的测试环境是:目标版本.NET Framework 4.5,
Unity 4.0.1
。如果你能修改你的例子来重现这个问题,我很乐意为你提供帮助。