我有一个.NET Core类库,它提供的功能可以被桌面和Web应用程序使用。我希望尽可能多地支持.NET Core支持的平台。
当在Web应用程序的上下文中运行时,我希望该库能够检测到应用程序所在的域。通常,我会使用 HttpContext.Request
对象,通过注入 IHttpContextAccessor
. 然而,一个桌面应用程序没有 HttpContext
.
有没有什么方法可以注入一个服务,使消费者中的引用在无法提供时为空?
如果应用程序是由桌面应用程序使用的,那么当有请求进来时,就不可能像Web应用程序那样使用HttpContext,所以我们需要一个解决方法。
鉴于你在应用程序中遵循命名惯例,我建议使用Reflection,并将应用程序名称读为
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
这应该是可行的。
所以,最后,在依赖注入配置中,我测试了一下默认的AspNet Core HttpContextAccessor
存在,如果不存在,我就传入一个HttpContext为空的假对象。
public void ConfigureServices(IServiceCollection services)
{
...
var accessorType = GetAccessorType() ?? typeof(NullOpHttpAccessor);
services.TryAddSingleton(typeof(IHttpContextAccessor), accessorType);
...
}
private static Type GetAccessorType()
{
var interfaceType = typeof(IHttpContextAccessor);
var excludedNames = new[] { "IHttpContextAccessor", "NullOpHttpAccessor" };
var type = AppDomain.CurrentDomain.GetAssemblies()
.AsEnumerable()
.SelectMany(a => a.GetTypes())
.FirstOrDefault(t => !excludedNames.Contains(t.Name) &&
interfaceType.IsAssignableFrom(t));
return type;
}
internal class NullOpHttpAccessor : IHttpContextAccessor
{
public HttpContext HttpContext { get => null; set => value = null; }
}
然后,在我的库中,我注入 HttpContextAccessor
,测试上下文是否为空,并进行相应的操作。
internal string DoStuff()
{
if (HttpContextAccessor.HttpContext == null)
{
return GetMacAddress();
}
return HttpContextAccessor.HttpContext.Request.Host.ToString();
}