我想在新的 .NET Core 世界中创建一个包含的库/服务。基本上我有几个 SASS 产品:
ServiceProduct1:有一个 UI/Composistion 根层不需要知道的存储库层。
ServiceProduct2:有一个 UI/Composistion 根层不需要知道的存储库层。它也有电子邮件服务。
这两个服务产品在多个应用程序中使用,但消费应用程序必须知道绑定(bind)隐藏在存储库中的接口(interface)。电子邮件服务也使用依赖注入(inject),它必须是 绑定(bind)在消费应用程序中,即使它被服务使用。
在 .NET Core 之前,我会使用递归来搜索 dll 以查找要绑定(bind)的内容:
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;
}
然后在使用的服务中,您将进行所有绑定(bind)。
我不再使用 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>();
}
}
我们现在可以想象支付服务的接口(interface)和相应的实现是这样的:
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
应用程序。
关于dependency-injection - 如何在 .NET Core 的该层绑定(bind)服务 dll 的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38903271/