Rah*_*rma 4 c# asp.net-mvc dependency-injection unity-container
因此,我使用 Unity MVC-4 来实现依赖注入,它非常适合我的Controller类,但是一旦我尝试注入我的非控制器类,我就会得到NullReferenceException,并且我可以看到我注入的对象没有由框架初始化。我会给你我正在使用的相应类:
Controller类(DI作品):
public class HomeController : Controller
{
IMyService _myService;
#region CTOR
public HomeController(IMyService myService)
{
_myService = myService;
}
#endregion
public string GetMyString()
{
string mystring=string.Empty;
try
{
mystring = _myService.GetMyStringFromDLL();
}
catch (Exception ex)
{
StringBuilder str = new StringBuilder();
str.AppendLine("Exception in method GetMyString, Error msg: " + ex.Message);
WriteLog(sb);
}
return mystring;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在非控制器方法中做同样的事情(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;
}
}
Run Code Online (Sandbox Code Playgroud)
我的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)
{
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在上面的行中看到container.RegisterType<IMyService , MyService>();,该接口及其具体实现位于单独的模块中。
我的Global.asax.cs是:
protected void Application_Start()
{
Bootstrapper.Initialise();
AreaRegistration.RegisterAllAreas();
GlobalFilters.Filters.Add(new OfflineActionFilter());
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Run Code Online (Sandbox Code Playgroud)
IMyService我怎样才能在课堂上注入MyLogic?
使用属性[InjectionConstructor]告诉 Unity 该类MyLogic依赖于要在构造函数中注入的对象:
[InjectionConstructor]
public MyLogic(IMyService myService)
{
_myService = myService;
}
Run Code Online (Sandbox Code Playgroud)
实际上,[InjectionConstructor]当注入的类包含多个构造函数时,建议使用。因此,属性用于解决歧义。这只是我的假设,为什么Unity无法解析所需的类型,因为问题代码不包含代码的所有部分。但在下面的测试代码中[InjectionConstructor]不需要该属性,因为只声明了一个构造函数。
这是测试代码。
接口IMyService定义:
public interface IMyService
{
string GetMyStringFromDLL();
}
Run Code Online (Sandbox Code Playgroud)
接口ILogic定义:
public interface IMyLogic
{
string GetMyString();
}
Run Code Online (Sandbox Code Playgroud)
实施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;
}
}
Run Code Online (Sandbox Code Playgroud)
实施MyService:
public class MyService : IMyService
{
public string GetMyStringFromDLL()
{
return "MyService.GetMyStringFromDLL() is called.";
}
}
Run Code Online (Sandbox Code Playgroud)
初始化Bootstrapper:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
控制器Home实现:
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} );
}
}
Run Code Online (Sandbox Code Playgroud)
最后,当Home执行控制器的默认操作方法时,将显示以下两行:
MyService.GetMyStringFromDLL() is called.
MyLogic.GetMyString() -> MyService.GetMyStringFromDLL() is called.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1306 次 |
| 最近记录: |