我不了解ASP.NET MVC初始化应用程序的方式。
据我所知,首先它执行App_Start
中的代码,跟随Global.asax.cs
文件,然后执行Startup.cs
,最后等待传入的Web请求。
大多数应用程序由一个背景层组成,即使没有人访问网页也会运行,另一个背景层提供HTTP请求。第一个执行系统的核心任务:与外部设备交换数据,更新数据库,读/写输入/输出文件等......当有人连接到网络服务器时," UI"图层将以网页的形式显示结果。
(为了简单起见,我假设"核心"层是ASP.NET项目中的一个类。当然,对于更大的应用程序,最好添加一个引用项目以保持事情的清洁,但我不应该对我的问题有任何不同,我希望)
基本的ASP.NET MVC模板允许配置Web层所需的服务,只需要web请求页面。 相反,我需要在Web应用程序的整个生命周期中添加一次我的基础类的初始化(即,直到服务器关闭)。
第一
阅读文档,我认为放置这个初始化函数的正确位置是App_Start
文件夹。我使用一些方法创建了我的Init
类来初始化不同的部分。
失败:因为它需要一个 static 类,所以它不能有构造函数,因此我无法注入依赖类(即DbContext
)。
第二
我使用Hangfire
,因此我尝试在Application_Start()
函数的末尾添加后台作业:
BackgroundJob.Enqueue<Erp>(x => x.Init());
失败:Application_Start()
函数在 Configuration()
之前执行(Startup.cs
),因此Hangfire
尚不可用。
第三
那么,如何将上面的行放在Configuration()
函数的末尾?
失败?不会生成错误,但我的类的构造函数和请求的方法都不会被执行。
供您参考,这是我的Erp
课程(我在这里复制相关部分):
public interface IErp
{
void Init();
Task ImportOrdersAsync();
}
public class Erp : IErp
{
private readonly IMyContext _context;
private readonly LiveData _liveData;
public Erp(IMyContext context, LiveData liveData)
{
_context = context;
_liveData = liveData;
}
public void Init()
{
_liveData.Plcs.Clear();
var machines = _context.Machines.ToList();
foreach (var machine in machines)
{
Plc plc = new Plc
{
Name = machine.Name,
Description = machine.Description,
};
_liveData.Plcs.Add(plc);
}
}
public async Task ImportOrdersAsync()
{
// do something
}
}
这里是Ninject
服务:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IMyContext>().To<MyContext>().InRequestScope();
kernel.Bind<IErp>().To<Erp>().InRequestScope();
kernel.Bind<LiveData>().To<LiveData>().InSingletonScope();
}
关于最小和可编译的示例:在默认MVC模板上添加此示例类(无论其内容)应该足够了。 无论如何,如果我忘记了任何重要的代码,请告诉我。