[英]HttpClientFactory how to inject into class I have no control over core 2.1
[英]How to inject a property into a class that I don't control the creation of
如何使用autofac將IServiceManager屬性注入此類? 這是一個自定義資源提供程序工廠類,當您調用HttpContext.GetGlobalResourceObject("", "MyResource")
以獲取資源字符串時,將調用該類。
public class SqlResourceProviderFactory : ResourceProviderFactory
{
// needs autofac property injection
public IServiceManager ServiceManager { get; set; }
public override IResourceProvider CreateGlobalResourceProvider(string classKey)
{
...
}
public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
{
...
}
public static string GetAppRelativePath(string logicalPath)
{
...
}
}
我曾經遇到過與ASP.NET ResourceProviderFactory
完全相同的問題,不幸的是,答案是必須使用service location 。
您可以在其中注入任何內容或更改內置ASP.NET行為的任何地方都沒有“鈎子”進入管道。 因此,如果需要將某些內容放入屬性,則必須在構造函數中進行設置。
public class SqlResourceProviderFactory : ResourceProviderFactory
{
public IServiceManager ServiceManager { get; set; }
public SqlResourceProviderFactory()
{
this.ServiceManager =
DependencyResolver.Current.GetService<IServiceManager>();
}
}
是的,這真的很丑。
在此要考慮的非常重要的事情,尤其是對於Autofac而言,是IServiceManager
注冊的生存期范圍。
ResourceProviderFactory
僅創建一次並緩存。 與Create *方法中的全局/本地資源提供程序相同。 我們花了很長時間,因為這意味着在創建工廠時不一定有HttpContext
,即使存在,如果下游依賴項已注冊InstancePerHttpRequest
它們也會被處理掉,而您重新軟管。
ResourceProviderFactory
或生成的資源提供者使用的所有內容(從堆棧一直到堆棧)都應注冊SingleInstance
或InstancePerDependency
。 DependencyResolver.Current
(對於Autofac,它需要一個活動的HttpContext
),請直接引用該應用程序容器。 這意味着您需要將對它的引用存儲在其他地方(全局靜態變量?)並使用它。 這是更完整的解決方案可能涉及的內容:
// Create some "holder" for the app container.
public static class ApplicationContainerProvider
{
public static ILifetimeScope Container { get; set; }
}
// In Global.asax, build your container and set it in both
// the DependencyResolver AND in the holder class.
var builder = new ContainerBuilder();
builder.RegisterType<Something>().As<ISomething>();
var container = builder.Build();
var resolver = new AutofacDependencyResolver(container);
DependencyResolver.SetResolver(resolver);
ApplicationContainerProvider.Container = container;
// In your service location, reference the container instead of
// DependencyResolver.
public class SqlResourceProviderFactory : ResourceProviderFactory
{
public IServiceManager ServiceManager { get; set; }
public SqlResourceProviderFactory()
{
this.ServiceManager =
ApplicationContainerProvider.Container.Resolve<IServiceManager>();
}
}
請注意,由於您要從根容器中解決該問題,因此它將在應用程序的整個生命周期內始終存在。 即使您將其注冊為InstancePerDependency
,由於.NET進行了內部緩存,它也只會被創建一次。
如果您不喜歡這樣創建自己的靜態持有Autofac.Extras.CommonServiceLocator
,則可以使用Autofac.Extras.CommonServiceLocator
和Autofac.Extras.CommonServiceLocator
包CommonServiceLocator
其Autofac.Extras.CommonServiceLocator
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.