Dependency injection 如何在ASP.Net核心MVC中向服务中注入repo
我有一个很奇怪的问题。Dependency injection 如何在ASP.Net核心MVC中向服务中注入repo,dependency-injection,asp.net-core-3.1,Dependency Injection,Asp.net Core 3.1,我有一个很奇怪的问题。 我已经为名为PageHits的数据库集定义了一个存储库 这是接口: public interface IPageHitRepo { IQueryable<PageHit> PageHits { get; } void AddPageHit(PageHit pageHit); void SaveChanges(); } 然后,PageHitService的顶部如下所示: services.AddScoped<IPageHitRep
我已经为名为PageHits的数据库集定义了一个存储库 这是接口:
public interface IPageHitRepo
{
IQueryable<PageHit> PageHits { get; }
void AddPageHit(PageHit pageHit);
void SaveChanges();
}
然后,PageHitService的顶部如下所示:
services.AddScoped<IPageHitRepo, PageHitRepo>();
public interface IPageHitService
{
// Default implimentation overridden in PageHitService.
Task Invoke(IServiceProvider sp) => Task.FromResult(true);
Task EmailSiteHitNotification(PageHit pageHit, IServiceProvider sp);
Task LogPageHitToDB(PageHit pageHit, IServiceProvider sp);
}
public class PageHitService : IPageHitService
{
private IPageHitRepo _pageHitRepo;
public PageHitService(IPageHitRepo pageHitRepo)
{
_pageHitRepo = pageHitRepo;
}
public async Task Invoke(IServiceProvider sp)
{
HttpContext httpContext =
sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
IWebHostEnvironment env = sp.GetRequiredService<IWebHostEnvironment>();
IConfiguration config = sp.GetRequiredService<IConfiguration>();
// _context = sp.GetRequiredService<CtasContext>();
bool visitSet =
!string.IsNullOrEmpty(httpContext.Session.GetString("VisitSet"));
调用是静态的,因为我在沿着工厂路线胡闹。
我不能调用非静态方法,所以我必须实例化一个实例来调用API中的2个方法。
现在没有任何东西是静态的,所以我将注释掉这一行,并尝试直接调用这些方法
下面是完整的课程:
public class PageHitService : IPageHitService
{
private IPageHitRepo _pageHitRepo;
public PageHitService(IPageHitRepo pageHitRepo)
{
_pageHitRepo = pageHitRepo;
}
public async Task Invoke(IServiceProvider sp)
{
HttpContext httpContext =
sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
IWebHostEnvironment env = sp.GetRequiredService<IWebHostEnvironment>();
IConfiguration config = sp.GetRequiredService<IConfiguration>();
// _context = sp.GetRequiredService<CtasContext>();
bool visitSet =
!string.IsNullOrEmpty(httpContext.Session.GetString("VisitSet"));
PageHit PageHit = new PageHit
{
SessionID = httpContext.Session.Id,
UserIP = httpContext.Connection.RemoteIpAddress.ToString(),
EnvironmentName = env.EnvironmentName,
Url = httpContext.Request.PathBase + httpContext.Request.Path,
ReferrerUrl = httpContext.Request.Headers["Referer"].ToString(),
DateTime = DateTime.Now
};
PageHitService pageHitService = new PageHitService();
bool logPageHitsOn = bool.Parse(config["LogPageHitsOn"]);
bool emailSiteHitNotificationsOn = bool.Parse(config["EmailSiteHitNotificationsOn"]);
if (!visitSet)
{
// create session
httpContext.Session.SetString("VisitSet", "true");
// Emails (1st visit of session)
if (emailSiteHitNotificationsOn)
{
await pageHitService.EmailSiteHitNotification(PageHit, sp);
}
}
// Logs all PageHits to DB.
if (logPageHitsOn)
{
await pageHitService.LogPageHitToDB(PageHit, sp);
}
}
public async Task EmailSiteHitNotification(PageHit pageHit,
IServiceProvider sp)
{
IEmailService emailService = sp.GetRequiredService<IEmailService>();
StringBuilder body = new StringBuilder();
body.AppendFormat($"<b>SessionID:</b> {pageHit.SessionID}");
body.Append("<br /><br />");
body.AppendFormat($"<b>User Ip:</b> {pageHit.UserIP}");
body.Append("<br /><br />");
body.AppendFormat($"<b>Environment:</b> {pageHit.EnvironmentName}");
body.Append("<br /><br />");
body.AppendFormat($"<b>Url (Page Hit):</b> {pageHit.Url}");
body.Append("<br /><br />");
body.AppendFormat($"<b>ReferrerUrl:</b> {pageHit.ReferrerUrl}");
body.Append("<br /><br />");
body.AppendFormat($"<b>DateTime:</b> {pageHit.DateTime}");
body.Append("<br /><br />");
string subject = "CTAS Hit Notification";
await emailService.SendEmail(body.ToString(), subject);
}
public async Task LogPageHitToDB(PageHit pageHit,
IServiceProvider sp)
{
CtasContext context = sp.GetRequiredService<CtasContext>();
await context.PageHits.AddAsync(pageHit);
await context.SaveChangesAsync();
}
}
公共类PageHitService:IPageHitService
{
私人IPageHitRepo_pageHitRepo;
公共PageHitService(IPageHitRepo pageHitRepo)
{
_pageHitRepo=pageHitRepo;
}
公共异步任务调用(IServiceProvider sp)
{
HttpContext HttpContext=
sp.GetRequiredService().HttpContext;
IWebHostenEnvironment env=sp.GetRequiredService();
IConfiguration config=sp.GetRequiredService();
//_context=sp.GetRequiredService();
布尔参观酒店=
!string.IsNullOrEmpty(httpContext.Session.GetString(“VisitSet”));
PageHit PageHit=新的PageHit
{
SessionID=httpContext.Session.Id,
UserIP=httpContext.Connection.RemoteIpAddress.ToString(),
EnvironmentName=env.EnvironmentName,
Url=httpContext.Request.PathBase+httpContext.Request.Path,
refererUrl=httpContext.Request.Headers[“Referer”].ToString(),
DateTime=DateTime.Now
};
PageHitService PageHitService=新的PageHitService();
bool logPageHitsOn=bool.Parse(config[“logPageHitsOn”]);
bool-emailSiteHitNotificationsOn=bool.Parse(配置[“emailSiteHitNotificationsOn]”);
如果(!visitSet)
{
//创建会话
httpContext.Session.SetString(“VisitSet”、“true”);
//电子邮件(课程第一次访问)
如果(emailSiteHitNotificationsOn)
{
等待pageHitService.EmailSiteHitNotification(PageHit,sp);
}
}
//将所有页面点击记录到数据库中。
if(logPageHitsOn)
{
等待pageHitService.LogPageHitToDB(PageHit,sp);
}
}
公共异步任务EmailSiteHitNotification(PageHit PageHit,
IServiceProvider sp)
{
IEmailService emailService=sp.GetRequiredService();
StringBuilder主体=新的StringBuilder();
AppendFormat($“SessionID:{pageHit.SessionID}”);
正文。追加(“
”);
AppendFormat($“用户Ip:{pageHit.UserIP}”);
正文。追加(“
”);
AppendFormat($“环境:{pageHit.EnvironmentName}”);
正文。追加(“
”);
AppendFormat($“Url(页面命中):{pageHit.Url}”);
正文。追加(“
”);
AppendFormat($“refererURL:{pageHit.refererURL}”);
正文。追加(“
”);
AppendFormat($“DateTime:{pageHit.DateTime}”);
正文。追加(“
”);
string subject=“CTAS命中通知”;
等待emailService.SendEmail(body.ToString(),subject);
}
公共异步任务日志PageHitToDB(PageHit PageHit,
IServiceProvider sp)
{
CtasContext context=sp.GetRequiredService();
wait context.PageHits.AddAsync(pageHit);
wait context.saveChangesSync();
}
}
您的代码中出现了一些您在问题中没有显示的内容。就目前而言,您的问题是不可重现的。因此,你的问题需要详细或清晰。您是否可能没有制作与代码完全相同的副本?可能还有一个名为IPageHitService
的(基类)?举个例子,看看这个。@Steven-谢谢你的关注。此服务没有基类。我有一个基本控制器和一个调用服务的基本页面模型。如果我添加一个私有构造函数,编译错误就会消失。这是因为我在IPageHitService的一个接口成员上有一个默认实现吗?我不同意所有这些。GetService可能会意外地从根容器中提取内容,这可能解释了为什么会得到ObjectDisposedEx。具有20个依赖项的基类可能表明该类存在问题。使用IServiceProvider应该仅限于合成根。很好,它正在工作。我能推荐一本关于依赖性的好书给你以拓宽你的知识面吗?依赖注入原则、实践和模式(由我合著)。
services.AddScoped<IPageHitService, PageHitService>();
public class BaseController : Controller
{
public BaseController(IServiceProvider sp)
{
IPageHitService pageHitService = sp.GetRequiredService<IPageHitService>();
// pageHitService.Invoke(sp).Await();
pageHitService.Invoke(sp).Wait();
}
#region Callbacks if you use AsyncMethod.Await() extension method.
private void Completed()
{
Console.WriteLine("Completed pageHitService.Invoke from BaseController");
}
private void HandleError(Exception ex)
{
// TODO: Log Error to DB;
}
#endregion
}
public class BasePageModel : PageModel
{
public BasePageModel(IServiceProvider sp)
{
IPageHitService pageHitService = sp.GetRequiredService<IPageHitService>();
// pageHitService.Invoke(sp).Await();
pageHitService.Invoke(sp).Wait();
}
#region Callbacks if you use AsyncMethod.Await() extension method.
private void Completed()
{
Console.WriteLine("Completed pageHitService.Invoke from BaseController");
}
private void HandleError(Exception ex)
{
// TODO: Log Error to DB;
}
#endregion
}
PageHitService pageHitService = new PageHitService();
public class PageHitService : IPageHitService
{
private IPageHitRepo _pageHitRepo;
public PageHitService(IPageHitRepo pageHitRepo)
{
_pageHitRepo = pageHitRepo;
}
public async Task Invoke(IServiceProvider sp)
{
HttpContext httpContext =
sp.GetRequiredService<IHttpContextAccessor>().HttpContext;
IWebHostEnvironment env = sp.GetRequiredService<IWebHostEnvironment>();
IConfiguration config = sp.GetRequiredService<IConfiguration>();
// _context = sp.GetRequiredService<CtasContext>();
bool visitSet =
!string.IsNullOrEmpty(httpContext.Session.GetString("VisitSet"));
PageHit PageHit = new PageHit
{
SessionID = httpContext.Session.Id,
UserIP = httpContext.Connection.RemoteIpAddress.ToString(),
EnvironmentName = env.EnvironmentName,
Url = httpContext.Request.PathBase + httpContext.Request.Path,
ReferrerUrl = httpContext.Request.Headers["Referer"].ToString(),
DateTime = DateTime.Now
};
PageHitService pageHitService = new PageHitService();
bool logPageHitsOn = bool.Parse(config["LogPageHitsOn"]);
bool emailSiteHitNotificationsOn = bool.Parse(config["EmailSiteHitNotificationsOn"]);
if (!visitSet)
{
// create session
httpContext.Session.SetString("VisitSet", "true");
// Emails (1st visit of session)
if (emailSiteHitNotificationsOn)
{
await pageHitService.EmailSiteHitNotification(PageHit, sp);
}
}
// Logs all PageHits to DB.
if (logPageHitsOn)
{
await pageHitService.LogPageHitToDB(PageHit, sp);
}
}
public async Task EmailSiteHitNotification(PageHit pageHit,
IServiceProvider sp)
{
IEmailService emailService = sp.GetRequiredService<IEmailService>();
StringBuilder body = new StringBuilder();
body.AppendFormat($"<b>SessionID:</b> {pageHit.SessionID}");
body.Append("<br /><br />");
body.AppendFormat($"<b>User Ip:</b> {pageHit.UserIP}");
body.Append("<br /><br />");
body.AppendFormat($"<b>Environment:</b> {pageHit.EnvironmentName}");
body.Append("<br /><br />");
body.AppendFormat($"<b>Url (Page Hit):</b> {pageHit.Url}");
body.Append("<br /><br />");
body.AppendFormat($"<b>ReferrerUrl:</b> {pageHit.ReferrerUrl}");
body.Append("<br /><br />");
body.AppendFormat($"<b>DateTime:</b> {pageHit.DateTime}");
body.Append("<br /><br />");
string subject = "CTAS Hit Notification";
await emailService.SendEmail(body.ToString(), subject);
}
public async Task LogPageHitToDB(PageHit pageHit,
IServiceProvider sp)
{
CtasContext context = sp.GetRequiredService<CtasContext>();
await context.PageHits.AddAsync(pageHit);
await context.SaveChangesAsync();
}
}