这是我的场景。我想使用后台任务将新闻稿发送给订阅的用户。这是由MailService完成的,后者具有UnitOfWork作为依赖项。
我尝试了docs.microsoft.com的解决方案 所以在我的情况下,我使用IMailService的方法而不是ILogger,但出现错误:
System.InvalidOperationException:'无法使用单例>'Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor'中的作用域服务>'Fit4You.Core.Data.IUnitOfWork'。
我不想使我的UnitOfWork或DbContext具有Singleton生存期。是否有可能以某种方式消耗范围为UnitOfWork的MailService依赖项?
我了解IServiceScopeFactory,但也许不知道如何正确使用它。
我正在使用.NET Core 2.2并内置接口IHostedService
ScopedMailService:
imageView.SetBackgroundColor(Android.Graphics.Color.Transparent);
ConsumeScopedMailService:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@drawable/successful"
android:layout_width="250dp"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:layout_height="140dp"
android:id="@+id/imageView1" />
Startup.cs:
public class ScopedMailService : IScopedMailService
{
private readonly IMailService mailService;
public ScopedMailService(IMailService mailService)
{
this.mailService = mailService;
}
public void DoWork()
{
mailService.SendNewsletterToSubscribedUsers();
}
}
MailService:
public class ConsumeScopedMailService : IHostedService
{
private Timer timer;
private readonly IMailService mailService;
public IServiceProvider Services { get; }
public ConsumeScopedMailService(IServiceProvider services, IMailService mailService)
{
Services = services;
this.mailService = mailService;
}
public Task StartAsync(CancellationToken cancellationToken)
{
var startTimeSpan = GetStartTimeSpan();
var periodTimeSpan = TimeSpan.FromSeconds(30);
timer = new Timer(DoWork, null, startTimeSpan, periodTimeSpan);
return Task.CompletedTask;
}
private void DoWork(object state)
{
using (var scope = Services.CreateScope())
{
var scopedMailService = scope.ServiceProvider.GetRequiredService<IScopedMailService>();
scopedMailService.DoWork();
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
timer?.Dispose();
}
private TimeSpan GetStartTimeSpan()
{
var currentTime = DateTime.Now.Ticks;
var executeTime = DateTime.Today.AddHours(8)
.AddMinutes(0)
.Ticks;
long ticks = executeTime - currentTime;
if (ticks < 0)
{
ticks = ticks + TimeSpan.TicksPerDay;
}
var startTimeSpan = new TimeSpan(ticks);
return startTimeSpan;
}
}
答案 0 :(得分:2)
单例ConsumeScopedMailService
通过其构造函数依赖于IMailService
:
public ConsumeScopedMailService(IServiceProvider services, IMailService mailService)
IMailService
可能是临时的,但实现它的类取决于作用域服务IUnitOfWork
。间接地,ConsumeScopedMailService
最终取决于作用域服务。
要解决此问题,IMailService mailService
应该删除。无论如何,已发布的代码中都没有使用它。