C#依赖注入:将多个接口注入其他服务

我想为另一个服务注入许多接口。 让我们看一下我想要注入其依赖项的2个服务。

内部Term.cs

private readonly IWSConfig WSConfig;
private readonly IMemoryCache MemCache;

public Term(IWSConfig wsConfig,IMemoryCache memoryCache)
{
    WSConfig = wsConfig;
    MemCache = memoryCache;
}


public async Task LoadData()
{
    List<ConfigTerm> configTerm = await WSConfig.GetData(); // This is a web service call
    ...
}

Inside Person.cs

private readonly PersonRepo PersonRepository;
private readonly IMemoryCache MemCache;
private readonly ITerm Term;
private readonly IWSLoadLeave LoadLeave;
private readonly IWSLoadPartics LoadPartics;

public Person(PersonRepo personRepository,IMemoryCache memCache,ITerm term,IWSLoadLeave loadLeave,IWSLoadPartics loadPartics)
{
    PersonRepository = personRepository;
    MemCache = memCache;
    Term = term;
    LoadLeave = loadLeave;
    LoadPartics = loadPartics;
}

Startup.cs中的代码

services.AddDbContext<DBContext>(opts => opts.UseOracle(RegistryReader.GetRegistryValue(RegHive.HKEY_LOCAL_MACHINE,Configuration["AppSettings:RegPath"],"DB.ConnectionString",RegWindowsBit.Win64)));
services.AddTransient<ILogging<ServiceLog>,ServiceLogRepo>();
services.AddSingleton<IMemoryCache,MemoryCache>();    
services.AddHttpClient<IWSConfig,WSConfig>();
services.AddHttpClient<IWSLoadLeave,WSLoadLeave>();
services.AddHttpClient<IWSLoadPartics,WSLoadPartics>();

var optionsBuilder = new DbContextOptionsBuilder<DBContext>(); // Can we omit this one and just use the one in AddDbContext?
optionsBuilder.UseOracle(RegistryReader.GetRegistryValue(RegHive.HKEY_LOCAL_MACHINE,RegWindowsBit.Win64));

services.AddSingleton<ITerm,Term>((ctx) => {
    WSConfig wsConfig = new WSConfig(new System.Net.Http.HttpClient(),new ServiceLogRepo(new DBContext(optionsBuilder.Options))); // Can we change this to the IWSConfig and the ILogging<ServiceLog>
    IMemoryCache memoryCache = ctx.GetService<IMemoryCache>();
    return new Term(wsConfig,memoryCache);
});
services.AddSingleton<IPerson,Person>((ctx) => {
    PersonRepo personRepo = new PersonRepo(new DBContext(optionsBuilder.Options)); // Can we change this?
    IMemoryCache memoryCache = ctx.GetService<IMemoryCache>();
    ITerm term = ctx.GetService<ITerm>();
    WSLoadLeave loadLeave = new WSLoadLeave(new System.Net.Http.HttpClient(),new ServiceLogRepo(new DBContext(optionsBuilder.Options))); // Can we change this?
    WSLoadPartics loadPartics = new WSLoadPartics(new System.Net.Http.HttpClient(),new ServiceLogRepo(new DBContext(optionsBuilder.Options))); // Can we change this?
    return new Person(personRepo,memoryCache,term,loadLeave,loadPartics);
});

但是这里和那里有些重复。我在上面的代码中将其标记为注释。 如何纠正?

[UPDATE 1]: 如果我使用以下命令从单例更改声明:

services.AddScoped<ITerm,Term>();
services.AddScoped<IPerson,Person>();

尝试使用DbContext插入记录时出现以下错误。

  

{System.ObjectDisposedException:无法访问已处置的对象。一种   导致此错误的常见原因是处理已解决的上下文   从依赖注入,然后稍后尝试使用相同的   应用程序中其他位置的上下文实例。如果您可能会发生这种情况   在上下文上调用Dispose()或将上下文包装在   使用语句。如果使用依赖注入,则应让   依赖项注入容器负责处理上下文   实例。对象名称:“ DBContext”。

在我的WSConfig中,它将继承基类。该基类还引用了ServiceLogRepo,它将调用DbContext将记录插入数据库中

在WSConfig中

public class WSConfig : WSBase,IWSConfig
{
    private HttpClient WSHttpClient;

    public WSConfig(HttpClient httpClient,ILogging<ServiceLog> serviceLog) : base(serviceLog)
    {
        WSHttpClient = httpClient;

        //...
    }

    //...
}

WSBase类:

public class WSBase : WSCall
{    
    private readonly ILogging<ServiceLog> ServiceLog;

    public WSBase(ILogging<ServiceLog> serviceLog) : base(serviceLog)
    {

    }

    ...
}

WSCall类:

public class WSCall 
{
    private readonly ILogging<ServiceLog> ServiceLog;

    public WSCall(ILogging<ServiceLog> serviceLog)
    {
        ServiceLog = serviceLog;
    }
    ....
}

以及ServiceLogRepo代码

public class ServiceLogRepo : ILogging<ServiceLog>
{
    private readonly DBContext _context;

    public ServiceLogRepo(DBContext context)
    {
        _context = context;
    }

    public async Task<bool> LogRequest(ServiceLog apiLogItem)
    {
        await _context.ServiceLogs.AddAsync(apiLogItem);
        int i = await _context.SaveChangesAsync();

        return await Task.Run(() => true);
    }
}

我在Startup.cs中还具有以下功能,以便在应用程序加载时进行Web服务调用。

public void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerFactory,ITerm term)
{
    ....
    System.Threading.Tasks.Task.Run(async () => await term.LoadData());
}

进入term.LoadData()时,似乎已经将DBContext处理掉了。

IT756623839 回答:C#依赖注入:将多个接口注入其他服务

首先使用适当的liftetime范围在ConfigureServices中正确注册所有必要的依赖项

services.AddDbContext<DBContext>(opts => opts.UseOracle(RegistryReader.GetRegistryValue(RegHive.HKEY_LOCAL_MACHINE,Configuration["AppSettings:RegPath"],"DB.ConnectionString",RegWindowsBit.Win64)));
services.AddTransient<ILogging<ServiceLog>,ServiceLogRepo>();
services.AddSingleton<IMemoryCache,MemoryCache>();    
services.AddHttpClient<IWSConfig,WSConfig>();
services.AddHttpClient<IWSLoadLeave,WSLoadLeave>();
services.AddHttpClient<IWSLoadPartics,WSLoadPartics>();

services.AddScoped<ITerm,Term>();
services.AddScoped<IPerson,Person>();

鉴于在Configure中被调用的方法的异步性质,DbContext在处理完之前就被废弃了。

现在,理想情况下,考虑到要实现的目标,您应该使用后台服务IHostedServive,该服务将在应用程序启动时启动。

public class TermHostedService : BackgroundService {
    private readonly ILogger<TermHostedService> _logger;

    public TermHostedService(IServiceProvider services,ILogger<ConsumeScopedServiceHostedService> logger) {
        Services = services;
        _logger = logger;
    }

    public IServiceProvider Services { get; }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
        _logger.LogInformation("Term Hosted Service running.");

        using (var scope = Services.CreateScope()) {
            var term = scope.ServiceProvider.GetRequiredService<ITerm>();    
            await term.LoadData();
            _logger.LogInformation("Data Loaded.");
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken) {
        _logger.LogInformation("Term Hosted Service is stopping.");    
        await Task.CompletedTask;
    }
}

在启动时注册

services.AddHostedService<TermHostedService>();

引用Background tasks with hosted services in ASP.NET Core

本文链接:https://www.f2er.com/3162696.html

大家都在问