如何在 .NET Core 的该层绑定服务 dll 的依赖项
How do you bind the dependencies of the service dll's at that layer in .NET Core
我想在新的 .NET Core 世界中创建一个包含的 libraries/services。基本上我有几个SASS产品:
ServiceProduct1:有一个 UI/Composistion 根层不需要知道的存储库层。
ServiceProduct2:有一个 UI/Composistion 根层不需要知道的存储库层。它也有电子邮件服务。
这两个服务产品在多个应用程序中使用,但消费应用程序必须知道绑定隐藏在存储库中的接口。电子邮件服务也使用依赖注入,它必须是
绑定在消费应用程序中,即使它被服务使用。
在 .NET Core 之前,我会使用递归来搜索 dll 以查找要绑定的内容:
public static IKernel LoadAssemblies(IKernel kernel)
{
var type = typeof(INinjectDependency);
var dependencies = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetMatchingTypesInAssembly(y => type.IsAssignableFrom(y) && y.IsClass));
var assemblies = dependencies.Select(Assembly.GetAssembly).Distinct();
kernel.Load(assemblies);
return kernel;
}
然后在使用的服务中进行所有绑定。
我不再使用 Ninject,但概念是一样的。现在除非你换成在构建时发布 dll,否则你不能再使用这种方法了。我不想发布我的 dll。
还有其他方法可以解决这个问题吗?
很多文档都专门针对 ASP.NET Core
的实现,因此我明白了为什么这令人困惑。答案很简单。如果您的服务是完整的可执行文件,即;编译后它们会生成一个 *.exe
然后你需要在启动时连接你的服务 - 在主入口点附近的某个地方。如果您的服务只是一个 *.dll
,那么您必须有一个主机应用程序(可执行文件)为您连接依赖项 - 然后将服务集合交给您,这样您就可以构建一个 IServiceProvider
。
Dependency Injection with .NET Core
上有一篇很棒的文章。以下是如何实现此目的的示例:
public class Host
{
public static void Main()
{
IServiceCollection serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var application = new Application(serviceCollection);
// Run
// ...
}
static void ConfigureServices(
IServiceCollection serviceCollection)
{
ILoggerFactory loggerFactory = new Logging.LoggerFactory();
serviceCollection.AddInstance<ILoggerFactory>(loggerFactory);
}
}
这里有一些标准的命名约定,请注意 ConfigureServices
。然后 Application
对象定义如下:
public class Application
{
public IServiceProvider Services { get; set; }
public ILogger Logger { get; set; }
public Application(IServiceCollection serviceCollection)
{
ConfigureServices(serviceCollection);
// The service-provider is not built until all services are configured.
Services = serviceCollection.BuildServiceProvider();
Logger =
Services.GetRequiredService<ILoggerFactory>()
.CreateLogger<Application>();
Logger.LogInformation("Application created successfully.");
}
public void MakePayment(PaymentDetails paymentDetails)
{
Logger.LogInformation(
$"Begin making a payment { paymentDetails }");
IPaymentService paymentService =
Services.GetRequiredService<IPaymentService>();
// ...
}
void ConfigureServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IPaymentService, PaymentService>();
}
}
我们现在可以想象支付服务的接口和相应的实现是这样的:
public class PaymentService: IPaymentService
{
public ILogger Logger { get; }
public PaymentService(ILoggerFactory loggerFactory)
{
Logger = loggerFactory?.CreateLogger<PaymentService>();
if (Logger == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}
Logger.LogInformation("PaymentService created");
}
}
备注
这不一定是 ASP.NET Core
申请。
我想在新的 .NET Core 世界中创建一个包含的 libraries/services。基本上我有几个SASS产品:
ServiceProduct1:有一个 UI/Composistion 根层不需要知道的存储库层。
ServiceProduct2:有一个 UI/Composistion 根层不需要知道的存储库层。它也有电子邮件服务。
这两个服务产品在多个应用程序中使用,但消费应用程序必须知道绑定隐藏在存储库中的接口。电子邮件服务也使用依赖注入,它必须是 绑定在消费应用程序中,即使它被服务使用。
在 .NET Core 之前,我会使用递归来搜索 dll 以查找要绑定的内容:
public static IKernel LoadAssemblies(IKernel kernel)
{
var type = typeof(INinjectDependency);
var dependencies = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetMatchingTypesInAssembly(y => type.IsAssignableFrom(y) && y.IsClass));
var assemblies = dependencies.Select(Assembly.GetAssembly).Distinct();
kernel.Load(assemblies);
return kernel;
}
然后在使用的服务中进行所有绑定。
我不再使用 Ninject,但概念是一样的。现在除非你换成在构建时发布 dll,否则你不能再使用这种方法了。我不想发布我的 dll。
还有其他方法可以解决这个问题吗?
很多文档都专门针对 ASP.NET Core
的实现,因此我明白了为什么这令人困惑。答案很简单。如果您的服务是完整的可执行文件,即;编译后它们会生成一个 *.exe
然后你需要在启动时连接你的服务 - 在主入口点附近的某个地方。如果您的服务只是一个 *.dll
,那么您必须有一个主机应用程序(可执行文件)为您连接依赖项 - 然后将服务集合交给您,这样您就可以构建一个 IServiceProvider
。
Dependency Injection with .NET Core
上有一篇很棒的文章。以下是如何实现此目的的示例:
public class Host
{
public static void Main()
{
IServiceCollection serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var application = new Application(serviceCollection);
// Run
// ...
}
static void ConfigureServices(
IServiceCollection serviceCollection)
{
ILoggerFactory loggerFactory = new Logging.LoggerFactory();
serviceCollection.AddInstance<ILoggerFactory>(loggerFactory);
}
}
这里有一些标准的命名约定,请注意 ConfigureServices
。然后 Application
对象定义如下:
public class Application
{
public IServiceProvider Services { get; set; }
public ILogger Logger { get; set; }
public Application(IServiceCollection serviceCollection)
{
ConfigureServices(serviceCollection);
// The service-provider is not built until all services are configured.
Services = serviceCollection.BuildServiceProvider();
Logger =
Services.GetRequiredService<ILoggerFactory>()
.CreateLogger<Application>();
Logger.LogInformation("Application created successfully.");
}
public void MakePayment(PaymentDetails paymentDetails)
{
Logger.LogInformation(
$"Begin making a payment { paymentDetails }");
IPaymentService paymentService =
Services.GetRequiredService<IPaymentService>();
// ...
}
void ConfigureServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<IPaymentService, PaymentService>();
}
}
我们现在可以想象支付服务的接口和相应的实现是这样的:
public class PaymentService: IPaymentService
{
public ILogger Logger { get; }
public PaymentService(ILoggerFactory loggerFactory)
{
Logger = loggerFactory?.CreateLogger<PaymentService>();
if (Logger == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
}
Logger.LogInformation("PaymentService created");
}
}
备注
这不一定是 ASP.NET Core
申请。