dependency-injection - 如何在 .NET Core 的该层绑定(bind)服务 dll 的依赖项

标签 dependency-injection asp.net-core single-responsibility-principle

我想在新的 .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/

相关文章:

c# - 如何注册两个实现然后在 .Net Core 依赖注入(inject)中获得一个

android - Dagger 2 的作用域可以比 Activity 生命周期短吗?

python - Flask View 方法和 SRP

c# - 什么是显示松耦合类和接口(interface)之间关系的好方法?

c# - 是否应始终遵守 SRP?

java - Spring - 使用@Configurable 和@Value 注释用新运算符创建对象

amazon-web-services - 将 ASP.NET Core 部署到 AWS Elastic Beanstalk,必须包含一个带有 '.runtimeconfig.json' 后缀错误的文件

asp.net-core - 如何在ASP.NET Core中间件中直接将响应主体设置为文件流?

c# - EF Core 迁移错误 : Object reference not set to an instance of an object

c# - 使用 ninject 和 c#.net 实现条件依赖注入(inject)