我想为另一个服务注入许多接口。 让我们看一下我想要注入其依赖项的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处理掉了。