C# AutoFac-在应用程序启动时初始化重型单件

C# AutoFac-在应用程序启动时初始化重型单件,c#,dependency-injection,asp.net-mvc-5,singleton,autofac,C#,Dependency Injection,Asp.net Mvc 5,Singleton,Autofac,我们的配置是MVC5 C#app,使用AutoFac 我们有很多单例,如果用第一个请求初始化,会给用户带来不好的体验,因为它们的初始化总共需要3-4秒。我们使用AutoFac进行依赖注入,我想知道是否有任何方法可以确保单例(或这些特定的单例)构建在App_Start上,这样我们就不会在用户发送第一个请求时浪费时间?如果没有,解决此问题的最佳方法是什么?解决这类问题的一般方法是在代理实现后隐藏这些重量级对象。通过这种方式,您可以在应用程序启动时直接触发初始化过程,而操作在后台运行,不需要阻止请求(

我们的配置是MVC5 C#app,使用AutoFac


我们有很多单例,如果用第一个请求初始化,会给用户带来不好的体验,因为它们的初始化总共需要3-4秒。我们使用AutoFac进行依赖注入,我想知道是否有任何方法可以确保单例(或这些特定的单例)构建在App_Start上,这样我们就不会在用户发送第一个请求时浪费时间?如果没有,解决此问题的最佳方法是什么?

解决这类问题的一般方法是在代理实现后隐藏这些重量级对象。通过这种方式,您可以在应用程序启动时直接触发初始化过程,而操作在后台运行,不需要阻止请求(除非它们在请求期间需要未初始化的数据)

如果您的代码如下所示:

// The abstraction in question
public interface IMyService
{
    ServiceData GetData();
}

// The heavy implementation
public class HeavyInitializationService : IMyServic {
    public HeavyInitializationService() {
        // Load data here
        Thread.Sleep(3000);
    }
    public ServiceData GetData() => ...
}
可以按如下方式创建代理:

public class LazyMyServiceProxy : IMyService {
    private readonly Lazy<IMyService> lazyService;
    public LazyMyServiceProxy(Lazy<IMyService> lazyService) {
        this.lazyService = lazyService;
    }
    public ServiceData GetData() => this.lazyService.Value.GetData();
}
Lazy<IMyService> lazyService = new Lazy<IMyService>(() =>
    new HeavyInitializationService());

container.Register<IMyService>(c => new LazyMyServiceProxy(lazyService))
    .SingleInstance();

// Trigger the creation of the heavy data on a background thread:
Task.Factory.StartNew(() => {
    // Triggers the creation of HeavyInitializationService on background thread.
    var v = lazyService.Value;
});
公共类LazyMyServiceProxy:IMyService{
私人只读懒散服务;
公共LazyMyServiceProxy(Lazy lazyService){
this.lazyService=lazyService;
}
public ServiceData GetData()=>this.lazyService.Value.GetData();
}
您可以按如下方式使用此代理:

public class LazyMyServiceProxy : IMyService {
    private readonly Lazy<IMyService> lazyService;
    public LazyMyServiceProxy(Lazy<IMyService> lazyService) {
        this.lazyService = lazyService;
    }
    public ServiceData GetData() => this.lazyService.Value.GetData();
}
Lazy<IMyService> lazyService = new Lazy<IMyService>(() =>
    new HeavyInitializationService());

container.Register<IMyService>(c => new LazyMyServiceProxy(lazyService))
    .SingleInstance();

// Trigger the creation of the heavy data on a background thread:
Task.Factory.StartNew(() => {
    // Triggers the creation of HeavyInitializationService on background thread.
    var v = lazyService.Value;
});
Lazy lazyService=new Lazy(()=>
新的HeavyInitializationService());
container.Register(c=>newlazymyserviceproxy(lazyService))
.SingleInstance();
//触发在后台线程上创建重数据:
Task.Factory.StartNew(()=>{
//触发在后台线程上创建HeavyInitializationService。
var v=懒散服务价值;
});

这可能是一个更好的解决方案,因为它在某种程度上绕过了应用程序启动时间过长的问题,但您也可以这样做。您可以在这里结合后台初始化策略来实现这一点。