如何在 .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 申请。