如何在多项目解决方案中使用 .net 核心依赖注入?
How to use .net core dependency injection in multiprojects solution?
我是 asp.net 核心的新手。
我想做的是构建多项目解决方案并使用依赖注入在项目之间传递接口。
我所知道的是,在 ASP.NET 核心项目中,我们在 startup.cs
文件中有 ConfigureServices
方法来注册我们的接口及其实现,如下所示:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddTransient<IMyInterface,MyImplementation>();
.....
}
如果您在同一个项目中有 class,这很好,但是如果我有多个项目怎么办?
通常我要做的是使用安装程序(Windsor 安装程序)创建单独的项目来注册所需的接口及其实现。
在 .net 核心中,我们可以通过创建静态 ServiceCollection();
并从中获取静态 IServiceProvider
来做到这一点,以便随时使用它来获取您注册的任何服务:
public static IServiceCollection _serviceCollection { get; private set; }
public static IServiceProvider serviceProvider { get; private set; }
public static RegisterationMethod() {
_serviceCollection = new ServiceCollection();
_serviceCollection.AddSingleton<IMyInterface,MyImplementation>();
.....
serviceProvider = _serviceCollection.BuildServiceProvider();
}
public T GetService<T>() where T : class
{
return serviceProvider.GetService<T>();
}
现在我们从 ower 启动项目调用 RegisterationMethod
并继续照常开发,始终在此 class.
中注册服务
这种方法的问题是,如果我在 ASP.NET 核心项目中使用它,我将有两个地方来注册服务,这个地方和 startup.cs
文件中有 ConfigureServices(IServiceCollection services)
的地方。
你可能会说,
OK pass IServiceCollection
you had in ConfigureServices(IServiceCollection services)
to the RegisterationMethod
you previously created, in this way you're using the same services collection that ASP.NET using.
但通过这种方式,我将与 .net core
的依赖注入模块紧密耦合。
有没有更干净的方法来做到这一点?或者我应该用 Windsor
替换默认的 DI 吗?
...in ASP.NET core project[s] we have ConfigureServices... to register our interfaces and their implementations... This is good if you have classes all in the same project, but what if I have multi projects?
拥有多个项目并不重要。同样的原则适用:
将组合根放在应用程序中,尽可能靠近入口点。
假设您有一个引用多个 class 库的应用程序。在您的应用程序的 Startup
class 中,使用 ConfigureServices
注册所有依赖项。在每个 class 库项目中,使用构造函数注入。您的 class 是在同一个项目还是不同的项目中都没有关系。
OK pass IServiceCollection you had in ConfigureServices(IServiceCollection services) to the RegisterationMethod you previously created, in this way you're using the same services collection that ASP.NET using.
是的,就是这样。这是 an example from the github.com/aspnet/logging repository:
public static IServiceCollection AddLogging(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));
return services;
}
根据您的评论...
...听起来您正试图避免在您的应用程序中使用 composition root。组合根是我们向依赖注入容器注册依赖的唯一位置。组合根尽可能靠近应用程序的入口点(例如 ConfigureServices
方法),它属于应用程序而不属于它的库。
我是 asp.net 核心的新手。
我想做的是构建多项目解决方案并使用依赖注入在项目之间传递接口。
我所知道的是,在 ASP.NET 核心项目中,我们在 startup.cs
文件中有 ConfigureServices
方法来注册我们的接口及其实现,如下所示:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddTransient<IMyInterface,MyImplementation>();
.....
}
如果您在同一个项目中有 class,这很好,但是如果我有多个项目怎么办?
通常我要做的是使用安装程序(Windsor 安装程序)创建单独的项目来注册所需的接口及其实现。
在 .net 核心中,我们可以通过创建静态 ServiceCollection();
并从中获取静态 IServiceProvider
来做到这一点,以便随时使用它来获取您注册的任何服务:
public static IServiceCollection _serviceCollection { get; private set; }
public static IServiceProvider serviceProvider { get; private set; }
public static RegisterationMethod() {
_serviceCollection = new ServiceCollection();
_serviceCollection.AddSingleton<IMyInterface,MyImplementation>();
.....
serviceProvider = _serviceCollection.BuildServiceProvider();
}
public T GetService<T>() where T : class
{
return serviceProvider.GetService<T>();
}
现在我们从 ower 启动项目调用 RegisterationMethod
并继续照常开发,始终在此 class.
中注册服务
这种方法的问题是,如果我在 ASP.NET 核心项目中使用它,我将有两个地方来注册服务,这个地方和 startup.cs
文件中有 ConfigureServices(IServiceCollection services)
的地方。
你可能会说,
OK pass
IServiceCollection
you had inConfigureServices(IServiceCollection services)
to theRegisterationMethod
you previously created, in this way you're using the same services collection that ASP.NET using.
但通过这种方式,我将与 .net core
的依赖注入模块紧密耦合。
有没有更干净的方法来做到这一点?或者我应该用 Windsor
替换默认的 DI 吗?
...in ASP.NET core project[s] we have ConfigureServices... to register our interfaces and their implementations... This is good if you have classes all in the same project, but what if I have multi projects?
拥有多个项目并不重要。同样的原则适用:
将组合根放在应用程序中,尽可能靠近入口点。
假设您有一个引用多个 class 库的应用程序。在您的应用程序的 Startup
class 中,使用 ConfigureServices
注册所有依赖项。在每个 class 库项目中,使用构造函数注入。您的 class 是在同一个项目还是不同的项目中都没有关系。
OK pass IServiceCollection you had in ConfigureServices(IServiceCollection services) to the RegisterationMethod you previously created, in this way you're using the same services collection that ASP.NET using.
是的,就是这样。这是 an example from the github.com/aspnet/logging repository:
public static IServiceCollection AddLogging(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
services.TryAdd(ServiceDescriptor.Singleton<ILoggerFactory, LoggerFactory>());
services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(Logger<>)));
return services;
}
根据您的评论...
...听起来您正试图避免在您的应用程序中使用 composition root。组合根是我们向依赖注入容器注册依赖的唯一位置。组合根尽可能靠近应用程序的入口点(例如 ConfigureServices
方法),它属于应用程序而不属于它的库。