如何用简单的注射器注射
How to inject with simple injector
我正在努力确定这是否是将依赖项从我的控制台应用程序 Main 方法注入到我的主应用程序 class 实例的正确方法。
我有以下代码:
计划Class
static void Main(string[] args)
{
var container = new SimpleInjector.Container();
// Registrations here.
container.Register<ILogger, FileLogger>();
//Verify the container.
container.Verify();
ILogger log = container.GetInstance<ILogger>();
log.Info("Logging From Main Method");
//Start Main Agent
MainAgent agent = new MainAgent(log);
agent.Start();
}
主代理Class
public class MainAgent
{
private ILogger log;
public MainAgent(ILogger _log)
{
log = _log;
}
public void Start()
{
//Main Application Code here.
Console.WriteLine("main Agent Started.");
log.Info("Logging through logger in MainAgent Class");
Console.ReadLine();
}
}
我有在 ASP.Net Core 中编写 DotNetCore 应用程序的背景,所以我习惯了 DI 的工作方式,将服务注册到管道中,它们都可供我挑选选择每个控制器的构造函数。
我担心的是我可能有 20-30 个服务,每次我“新建”一个 class 的新实例时,所有这些都需要作为参数注入才能使它们可用到我的新 class.
中的构造函数
我是否缺少一些神奇的功能,它只会让我所有注册的服务在任何新初始化的构造函数中可用,供我参考,就像我使用 ASP.Net Core 一样?
不,没有魔法。
您缺少的是 AspNetCore 在幕后自动解析您的控制器,它解析控制器具有的依赖项的整个 对象图(即控制器的任何依赖项,这些依赖项的依赖项等)
同样,在控制台应用程序中,您需要解析整个对象图(通常在启动时)。
static void Main(string[] args)
{
// Begin Composition Root
var container = new SimpleInjector.Container();
// Registrations here.
container.Register<ILogger, FileLogger>();
container.Register<IMainAgent, MainAgent>();
//Verify the container.
container.Verify();
// End Composition Root
MainAgent agent = container.GetInstance<IMainAgent>();
//Start Main Agent
agent.Start();
}
实际上 "agent" 应该被视为 整个应用程序 。控制台只是一个 shell 来启动一切。请注意,在大多数情况下,从控制台应用程序传递参数可能是明智的,因此 "agent" 可以根据需要解析和响应它们。
agent.Start(args);
Am I missing some magical feature which will just make all my registered services available in any
简单回答是你是 SimpleInjector 支持直接创建对象
var agent = container.GetInstance<MainAgent>();
完全不需要注册实例。
您可以创建一个接口,然后像注册 ILogger 一样进行注册,但是将方法设为虚拟并直接使用 class 名称也可以。您可以阅读有关该主题的更多信息 here
我正在努力确定这是否是将依赖项从我的控制台应用程序 Main 方法注入到我的主应用程序 class 实例的正确方法。
我有以下代码:
计划Class
static void Main(string[] args)
{
var container = new SimpleInjector.Container();
// Registrations here.
container.Register<ILogger, FileLogger>();
//Verify the container.
container.Verify();
ILogger log = container.GetInstance<ILogger>();
log.Info("Logging From Main Method");
//Start Main Agent
MainAgent agent = new MainAgent(log);
agent.Start();
}
主代理Class
public class MainAgent
{
private ILogger log;
public MainAgent(ILogger _log)
{
log = _log;
}
public void Start()
{
//Main Application Code here.
Console.WriteLine("main Agent Started.");
log.Info("Logging through logger in MainAgent Class");
Console.ReadLine();
}
}
我有在 ASP.Net Core 中编写 DotNetCore 应用程序的背景,所以我习惯了 DI 的工作方式,将服务注册到管道中,它们都可供我挑选选择每个控制器的构造函数。
我担心的是我可能有 20-30 个服务,每次我“新建”一个 class 的新实例时,所有这些都需要作为参数注入才能使它们可用到我的新 class.
中的构造函数我是否缺少一些神奇的功能,它只会让我所有注册的服务在任何新初始化的构造函数中可用,供我参考,就像我使用 ASP.Net Core 一样?
不,没有魔法。
您缺少的是 AspNetCore 在幕后自动解析您的控制器,它解析控制器具有的依赖项的整个 对象图(即控制器的任何依赖项,这些依赖项的依赖项等)
同样,在控制台应用程序中,您需要解析整个对象图(通常在启动时)。
static void Main(string[] args)
{
// Begin Composition Root
var container = new SimpleInjector.Container();
// Registrations here.
container.Register<ILogger, FileLogger>();
container.Register<IMainAgent, MainAgent>();
//Verify the container.
container.Verify();
// End Composition Root
MainAgent agent = container.GetInstance<IMainAgent>();
//Start Main Agent
agent.Start();
}
实际上 "agent" 应该被视为 整个应用程序 。控制台只是一个 shell 来启动一切。请注意,在大多数情况下,从控制台应用程序传递参数可能是明智的,因此 "agent" 可以根据需要解析和响应它们。
agent.Start(args);
Am I missing some magical feature which will just make all my registered services available in any
简单回答是你是 SimpleInjector 支持直接创建对象
var agent = container.GetInstance<MainAgent>();
完全不需要注册实例。 您可以创建一个接口,然后像注册 ILogger 一样进行注册,但是将方法设为虚拟并直接使用 class 名称也可以。您可以阅读有关该主题的更多信息 here