简体   繁体   English

AutoFac - 在app_start上初始化重量级单身人士

[英]AutoFac - Initialize heavy-weight singletons on app_start

Our configuration is, MVC5 C# app, using AutoFac. 我们的配置是MVC5 C#app,使用AutoFac。

We have a number of singletons, which if they're initialized with the first request, causes a bad experience for the user, because their initialization takes around 3-4 seconds in total. 我们有许多单例,如果它们在第一次请求时初始化,会给用户带来糟糕的体验,因为它们的初始化总共花费大约3-4秒。 We're using AutoFac for Dependency injection, I'm wondering if there's any way of making sure the singletons (or these specific ones) are built on App_Start so we don't lose time when the user sends the first request? 我们正在使用AutoFac进行依赖注入,我想知道是否有任何方法可以确保单个(或这些特定的)是在App_Start上构建的,这样我们就不会在用户发送第一个请求时浪费时间? If not, what's the best way of solving this problem? 如果没有,解决这个问题的最佳方法是什么?

The general solution to this type of problem is to hide such heavy weight objects after a proxy implementation. 这类问题的一般解决方案是在代理实现后隐藏这样的重量级对象。 This way you can trigger the initialization process directly at application startup, while the operation runs in the background without requests to be blocked (unless they require the uninitialized data during their request). 这样,您可以在应用程序启动时直接触发初始化过程,而操作在后台运行而不会阻止请求(除非它们在请求期间需要未初始化的数据)。

In case your code looks like this: 如果您的代码如下所示:

// 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() => ...
}

A proxy can be created as follows: 可以按如下方式创建代理:

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

You can use this proxy as follows: 您可以按如下方式使用此代理:

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;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM