【发布时间】:2018-06-26 09:19:25
【问题描述】:
我知道有很多类似的问题,但实际上没有一个能解决我的问题。
我创建了一个新的 Asp.Net Core 2 应用程序。
现在我正在尝试对特定服务使用拦截器来获取一些数据到该服务中(我正在使用Castle.Corenuget 包)。
我有一个通用的IConfigurationInterceptor<> 和一个真正的实现ConfigurationInterceptor<>
界面如下:
public interface IConfigurationInterceptor<T> : IInterceptor where T : class { }
public class ConfigurationInterceptor<T> : IConfigurationInterceptor<T> where T : class
{
public ConfigurationInterceptor(ConfigurationInfo<T> configurationInfo,
some other services)
{
_configurationInfo = configurationInfo;
//.....
}
public void Intercept(IInvocation invocation)
{
invocation.ReturnValue = somefunc(someconfig, invocation.Arguments);
}
}
然后我有一个扩展方法如下:
public static void AddSingletonConfiguration<TInterface, TImplementation>(
this IServiceCollection services, string featureName)
where TImplementation : class, TInterface where TInterface : class
{
var info = new ConfigurationInfo<TImplementation>(featureName, typeof(TInterface));
var generator = new ProxyGenerator();
services.AddSingleton(x =>
{
var ic = x.GetService<Func<ConfigurationInfo<TImplementation>,
IConfigurationInterceptor<TImplementation>>>();
var icTemp = ic.Invoke(info);
return (TInterface) generator.CreateInterfaceProxyWithoutTarget(
info.ServiceType, icTemp);
});
}
但是当我到达这行代码时:
var ic = x.GetService<Func<ConfigurationInfo<TImplementation>,
IConfigurationInterceptor<TImplementation>>>();
它返回一个空值 ic:
ConfigurationInfo 类只是我为存储一些额外数据而创建的一个简单类。
public sealed class ConfigurationInfo<TImpl>
{
public Type ServiceType { get; }
public string FeatureName { get; }
public ConfigurationInfo(string featureName, Type serviceType)
{
FeatureName = featureName;
ServiceType = serviceType;
}
public override string ToString()
=> $"{FeatureName} ({ServiceType} -> {typeof(TImpl)})";
}
在我的ConfigureServices 我有这两行:
services.AddSingleton(typeof(IConfigurationInterceptor<>),
typeof(ConfigurationInterceptor<>));
services.AddSingletonConfiguration<IStaticDataConfiguration, StaticDataConfiguration>(
"SomeFeatureKey");
我不确定为什么ic 变量为空,因为之前另一个项目正在使用 Autofac 并且运行良好,但在启动时你会发现类似这样的内容:
builder.RegisterGeneric(typeof(ConfigurationInterceptor<>))
.As(typeof(IConfigurationInterceptor<>)).SingleInstance();
builder.RegisterConfiguration<IStaticDataConfiguration, StaticDataConfiguration>(
"SomeFeatureKey");
扩展方法是这样的:
public static void RegisterConfiguration<TInterface, TImplementation>(
this ContainerBuilder builder, string featureName)
where TImplementation : class, TInterface
{
var info = new ConfigurationInfo<TImplementation>(featureName, typeof(TInterface));
var generator = new ProxyGenerator();
builder
.Register(c =>
{
var ic = c.Resolve<Func<ConfigurationInfo<TImplementation>,
IConfigurationInterceptor<TImplementation>>>()(info);
return generator.CreateInterfaceProxyWithoutTarget(info.ServiceType, ic);
})
.As<TInterface>()
.SingleInstance();
}
任何帮助都将不胜感激。
编辑 1:
现在我从方法 GetService<> 更改为方法 GetRequiredService<> 并抛出如下异常:
“System.Func'2[StaticDataProvider.DomainModel.ConfigurationInfo'1[StaticDataProvider.Services.StaticDataConfiguration],StaticDataProvider.Services.Interfaces.IConfigurationInterceptor'1[StaticDataProvider.Services.StaticDataConfiguration]]”类型的服务未注册.
编辑 2:
在这里总结一下,问题是:在我当前的 Asp.Net 核心项目中,我无法获得 Func<X, B>,而在 Asp.Net MVC 5 项目中(这是一个完全不同的项目)我可以获得Func<X, B> 使用 Autofac。我认为这与 Autofac 默认提供的参数化实例化功能有关:here
现在,我不知道在 Asp.Net Core 默认 DI 容器中是否有类似“参数化实例化”的功能,它允许我解析 Func<X, B> 而不是 B。
【问题讨论】:
-
.Net Core 要求你手动注册你想通过 di 抓取的 Func
标签: c# dependency-injection autofac asp.net-core-2.0 castle