AutofaC语言 从 DependencyResolver.Current.GetService<>() 创建的 InstancePerRequest - 何时发布?



在.NET中的API控制器项目中,我正在使用的服务,例如SomeService,仅需要一次初始化(不是每个请求或每个someService实例)(尽管我没有)认为这是相关的,这里对此一部分的解释:它在创建API时在Azure存储中进行一些设置。对于SomeService的每个实例,执行此操作都是不必要的成本。因此,Global.asax

new SomeService().Init();

现在,我正在使用Autofac进行依赖注入。我将SomeService注册为ISomeServiceInstancePerRequest(因为SomeService不是线程安全)。因此,现在我想通过容器中的实例在global.asax中初始化someService。但是,如果我尝试像

中的容器中获取一个实例
container.Resolve<ISomeService>().Init();

它给出了此错误

An exception of type 'Autofac.Core.DependencyResolutionException' occurred in Autofac.dll but was not handled in user code
Additional information: No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

因此,在global.asax中,我得到了错误说明中建议的实例。

DependencyResolver.Current.GetService<ISomeService>().Init();

我想知道的是,我从Current获得的SomeService实例是发布的吗?由于没有真正的请求,我不确定。在最糟糕的情况下,我可以使用new的混凝土获得实例。

您正在尝试将2个职责合并为1个组件,这些责任破坏了单一责任原则

为了解决它,您可以使用将初始化Azure存储(例如IStorageProvider)的组件和另一个可以执行作业的组件来拆分组件。IStorageProvider将被声明为SingleInstance(并在需要时实现IStartable),另一个组件将使用此组件。

public class AzureStorageProvider : IStorageProvider, IStartable
{
    public void Start()
    {
        // initialize storage
        this._storage = new ...
    }
} 

public class SomeService : ISomeService
{
    public SomeService(IStorageProvider storageProvider) 
    { 
        this._storageProvider = storageProvider;
    }
    private readonly IStorageProvider _storageProvider; 
    public void Do()
    {
        // do things with storage
        this._storageProvider.Storage.ExecuteX(); 
    }
}

和注册:

builder.RegisterType<AzureStorageProvider>().As<IStorageProvider>().SingleInstance(); 
builder.RegisterType<SomeService>().As<ISomeService>().InstancePerRequest();

您还可以注册IStorage,并让SomeService直接取决于IStorage,并将IStorageProvider用作工厂。

builder.Register(c => c.Resolve<IStorageProvider>().Storage).As<IStorage>(); 

相关内容

  • 没有找到相关文章

最新更新