【问题标题】:Passing a lot of different params into factoryPassing a lot of different params into factory
【发布时间】:2022-12-02 00:08:37
【问题描述】:

What is a better way pass a bunch of params to the factory. Not injecting them all to Class where factory is calling and passing them out? I have abstract class with three implementation. And for each implementation I have two different http services and one db service. I.e.

public class class1Implementation: someAbstractClass
{
    private readonly IHttpOneFirstService _httpOneFirstService;
    private readonly IHttpOneSecondService _httpOneSecondService;
    private readonly IDbOneService _dbOneService;
    
}
public class class2Implementation: someAbstractClass
{
    private readonly IHttpTwoFirstService _httpTwoFirstService;
    private readonly IHttpTwoSecondService _httpTwoSecondService;
    private readonly IDbTwoService _dbTwoService;
    
}
public class class3Implementation: someAbstractClass
{
    private readonly IHttpThreeFirstService _httpThreeFirstService;
    private readonly IHttpThreeSecondService _httpThreeSecondService;
    private readonly IDbThreeService _dbThreeService;
    
}

public class CustomWorker : BackgroundService
{
    private readonly IHttpOneFirstService _httpOneFirstService;
    private readonly IHttpOneSecondService _httpOneSecondService;
    private readonly IHttpTwoFirstService _httpTwoFirstService;
    private readonly IHttpTwoSecondService _httpTwoSecondService;
    private readonly IHttpThreeFirstService _httpThreeFirstService;
    private readonly IHttpThreeSecondService _httpThreeSecondService;
    private readonly IDbOneService _dbOneService;
    private readonly IDbTwoeService _dbTwoService;
    private readonly IDbThreeService _dbThreeService;
    
    private someAbstractClass myFactory(int condition)
    {
        someAbstractClass impl = condition switch
        {
            0 => new class1Implementation(_httpOneFirstService, _httpOneSecondService, _dbOneService),
            1 => new class2Implementation(_httpTwoFirstService, _httpTwoSecondService, _dbTwoService),
            _ => new class3Implementation(_httpThreeFirstService, _httpThreeSecondService, _dbThreeService),*/
        };
        return impl;
    }
}

【问题讨论】:

  • Have you considered using a dependency injection container? That might give you an easier way to create your objects.

标签: c#


【解决方案1】:

Assuming you're using DI container. To reduce code, you may declare Factory to be a record class (available from C# 9). For record types, constructor with properties initializion is being generated automatically, so less code here.

Then if register it in the DI container, container will instantiate Factory object automatically, passing corresponded parameters according to registered types. An example with built-in .NET DI container:

using System;
using Microsoft.Extensions.DependencyInjection;

public record class Factory(
    IHttpOneFirstService httpOneFirstService,
    IHttpOneSecondService httpOneSecondService,
    IHttpTwoFirstService httpTwoFirstService,
    IHttpTwoSecondService httpTwoSecondService,
    IHttpThreeFirstService httpThreeFirstService,
    IHttpThreeSecondService httpThreeSecondService,
    IDbOneService dbOneService,
    IDbTwoService dbTwoService,
    IDbThreeService dbThreeService) {
    
    public someAbstractClass Create(int condition)
    {
        return condition switch
        {
            0 => new class1Implementation(httpOneFirstService, httpOneSecondService, dbOneService),
            1 => new class2Implementation(httpTwoFirstService, httpTwoSecondService, dbTwoService),
            _ => new class3Implementation(httpThreeFirstService, httpThreeSecondService, dbThreeService)
        };
    }
}

public class Program
{
    public static void Main()
    {
        var serviceProvider = new ServiceCollection()
            .AddLogging()
            .AddScoped<IHttpOneFirstService, HttpOneFirstService>()
            .AddScoped<IHttpOneSecondService, HttpOneSecondService>()
            .AddScoped<IDbOneService, DbOneService>()
            .AddScoped<IHttpTwoFirstService, HttpTwoFirstService>()
            .AddScoped<IHttpTwoSecondService, HttpTwoSecondService>()
            .AddScoped<IDbTwoService, DbTwoService>()
            .AddScoped<IHttpThreeFirstService, HttpThreeFirstService>()
            .AddScoped<IHttpThreeSecondService, HttpThreeSecondService>()
            .AddScoped<IDbThreeService, DbThreeService>()
            .AddScoped<Factory>()
            .BuildServiceProvider();
        
        var factory = serviceProvider.GetService<Factory>();
        var obj = factory.Create(2);
        
        Console.WriteLine($"Factory created: {obj.GetType()} object");
    }
}

public abstract class someAbstractClass{} 

public interface IHttpOneFirstService {}
public interface IHttpOneSecondService {}
public interface IDbOneService {}
public interface IHttpTwoFirstService {}
public interface IHttpTwoSecondService {}
public interface IDbTwoService {}
public interface IHttpThreeFirstService {}
public interface IHttpThreeSecondService {}
public interface IDbThreeService {}

internal class HttpOneFirstService: IHttpOneFirstService {}
internal class HttpOneSecondService: IHttpOneSecondService {}
internal class DbOneService: IDbOneService {}
internal class HttpTwoFirstService: IHttpTwoFirstService {}
internal class HttpTwoSecondService: IHttpTwoSecondService {}
internal class DbTwoService: IDbTwoService {}
internal class HttpThreeFirstService: IHttpThreeFirstService {}
internal class HttpThreeSecondService: IHttpThreeSecondService {}
internal class DbThreeService: IDbThreeService {}

public class class1Implementation: someAbstractClass
{
    private readonly IHttpOneFirstService _httpOneFirstService;
    private readonly IHttpOneSecondService _httpOneSecondService;
    private readonly IDbOneService _dbOneService;
    public class1Implementation(IHttpOneFirstService httpOneFirstService, IHttpOneSecondService httpOneSecondService, IDbOneService dbOneService) {
        _httpOneFirstService = httpOneFirstService;
        _httpOneSecondService = httpOneSecondService;
        _dbOneService = dbOneService;
    }
}
public class class2Implementation: someAbstractClass
{
    private readonly IHttpTwoFirstService _httpTwoFirstService;
    private readonly IHttpTwoSecondService _httpTwoSecondService;
    private readonly IDbTwoService _dbTwoService;
    public class2Implementation(IHttpTwoFirstService httpTwoFirstService, IHttpTwoSecondService httpTwoSecondService, IDbTwoService dbTwoService) {
        _httpTwoFirstService = httpTwoFirstService;
        _httpTwoSecondService = httpTwoSecondService;
        _dbTwoService = dbTwoService;
    }
    
}
public class class3Implementation: someAbstractClass
{
    private readonly IHttpThreeFirstService _httpThreeFirstService;
    private readonly IHttpThreeSecondService _httpThreeSecondService;
    private readonly IDbThreeService _dbThreeService;
    public class3Implementation(IHttpThreeFirstService httpThreeFirstService, IHttpThreeSecondService httpThreeSecondService, IDbThreeService dbThreeService) {
        _httpThreeFirstService = httpThreeFirstService;
        _httpThreeSecondService = httpThreeSecondService;
        _dbThreeService = dbThreeService;
    }    
}

【讨论】:

    猜你喜欢
    • 2022-12-02
    • 2022-12-02
    • 2022-11-09
    • 2019-06-24
    • 2023-02-25
    • 2022-12-01
    • 1970-01-01
    • 2022-12-02
    • 2022-12-02
    相关资源
    最近更新 更多