Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法使用ASP.NET Core 2和Castle.Core的手动拦截来解析一般服务_C#_Dependency Injection_Autofac_Asp.net Core 2.0_Castle - Fatal编程技术网

C# 无法使用ASP.NET Core 2和Castle.Core的手动拦截来解析一般服务

C# 无法使用ASP.NET Core 2和Castle.Core的手动拦截来解析一般服务,c#,dependency-injection,autofac,asp.net-core-2.0,castle,C#,Dependency Injection,Autofac,Asp.net Core 2.0,Castle,我知道有很多类似的问题,但实际上没有一个解决了我的问题。 我创建了一个新的Asp.NETCore2应用程序。 现在,我尝试使用特定服务的拦截器将一些数据获取到此服务中(我使用的是Castle.Corenuget包)。 我有一个通用的IConfigurationInterceptor和一个真正的实现ConfigurationInterceptor 以下是界面: public interface IConfigurationInterceptor<T> : IInterceptor wh

我知道有很多类似的问题,但实际上没有一个解决了我的问题。 我创建了一个新的Asp.NETCore2应用程序。 现在,我尝试使用特定服务的拦截器将一些数据获取到此服务中(我使用的是
Castle.Core
nuget包)。 我有一个通用的
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);
    }
}
在我的
ConfigureServices
中,我有以下两行:

services.AddSingleton(typeof(IConfigurationInterceptor<>), 
    typeof(ConfigurationInterceptor<>));
services.AddSingletonConfiguration<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();
}
公共静态无效注册表配置(
此ContainerBuilder生成器,字符串特征名称)
其中TImplementation:类,TInterface
{
var info=新配置信息(功能名称、类型(TInterface));
var生成器=新的ProxyGenerator();
建设者
.寄存器(c=>
{
var ic=c.Resolve()(信息);
返回生成器.CreateInterfaceProxyWithoutTarget(info.ServiceType,ic);
})
.As()
.SingleInstance();
}
任何帮助都会得到报答

编辑1:

现在,我从方法
GetService
更改为方法
GetRequiredService
,并引发如下异常:

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);
    });
}
public void ConfigureServices(IServiceCollection services)
{
    IConfigurationInterceptor<T> GetConfigurationInterceptor<T>(ConfigurationInfo<T> info) where T : class 
    { 
        return new ConfigurationInterceptor<T>(info, services.GetService<IConfigurationProvider>(), Configuration);
    }

    services.AddSingletonConfiguration<IStaticDataConfiguration, StaticDataConfiguration>("someFeatureKey", GetConfigurationInterceptor);
 }
public static void AddSingletonConfiguration<TInterface, TImplementation>(this IServiceCollection services, 
    string featureName, Func<ConfigurationInfo<TImplementation>, IConfigurationInterceptor<TImplementation>> ic) where TImplementation : class, TInterface where TInterface : class
{ 
    var info = new ConfigurationInfo<TImplementation>(featureName, typeof(TInterface));
    var generator = new ProxyGenerator();
    services.AddSingleton(x =>
    {
        var icTemp = ic.Invoke(info);
        return (TInterface) generator.CreateInterfaceProxyWithoutTarget(info.ServiceType, icTemp);
    });
}
public static TInterface GetService<TInterface>(this IServiceCollection services) where TInterface : class
{ 
    var serviceProvider = services.BuildServiceProvider();
    return serviceProvider.GetRequiredService<TInterface>();
}
“System.Func'2[StaticDataProvider.DomainModel.ConfigurationInfo'1[StaticDataProvider.Services.StaticDataConfiguration],StaticDataProvider.Services.Interfaces.IConfigurationInterceptor'1[StaticDataProvider.Services.StaticDataConfiguration]]”类型的服务尚未注册

编辑2:

总而言之,问题是:在我当前的Asp.Net core项目中,我无法获得
Func
,而在Asp.Net MVC 5项目中(这是一个完全不同的项目),我可以使用Autofac获得
Func
。我认为这与Autofac默认提供的参数化实例化功能有关:


现在,我不知道Asp.Net核心默认DI容器中是否有类似这种“参数化实例化”功能,它允许我解析
Func
,而不是
B
,,我猜问题的根源在于拦截器相当复杂的手动布线

如果您将拦截器与Autofac一起使用,最好使用
Autofac.Extras.dynamicProxy 2
包,而不是尝试将一系列分辨率与函数和参数链接在一起。我在这里看到了很多小问题,比如如何在没有目标的情况下设置单例接口代理,但我不完全清楚如何在事后添加目标。使用提供的工具可以避免很多复杂性

也就是说,我也在查看异常消息。如果没有堆栈跟踪,我无法100%保证,但在Autofac源上搜索表明,这不是来自Autofac的消息-很可能是来自默认Microsoft.Extensions.DependencyInjection容器的消息。这表明你可能并没有像你想象的那样把每件事都联系起来

我会备份一点,让简单的东西正常工作,并确保它们来自Autofac。如果您决定不使用Autofac,请确保已将其从等式中完全删除。基本上,只要确保它是干净的,并在一般意义上工作


之后,慢慢地把东西加回去,一次一个。我可能会建议在单元测试中进行复制,在单元测试中,您可以使用这些注册机制,并在不降低整个应用程序复杂性的情况下工作。从那里解开它。如果它太复杂而无法进行单元测试。。。也许这是一个指标,你应该简化它并重构它。使其可测试。

我猜问题的根源在于拦截器相当复杂的手动接线

如果您将拦截器与Autofac一起使用,最好使用
Autofac.Extras.dynamicProxy 2
包,而不是尝试将一系列分辨率与函数和参数链接在一起。我在这里看到了很多小问题,比如如何在没有目标的情况下设置单例接口代理,但我不完全清楚如何在事后添加目标。使用提供的工具可以避免很多复杂性

也就是说,我也在查看异常消息。如果没有堆栈跟踪,我无法100%保证,但在Autofac源上搜索表明,这不是来自Autofac的消息-很可能是来自默认Microsoft.Extensions.DependencyInjection容器的消息。这表明你可能并没有像你想象的那样把每件事都联系起来

我会备份一点,让简单的东西正常工作,并确保它们来自Autofac。如果您决定不使用Autofac,请确保已将其从等式中完全删除。基本上,只要确保它是干净的,并在一般意义上工作


之后,慢慢地把东西加回去,一次一个。我可能会建议在单元测试中进行复制,在单元测试中,您可以使用这些注册机制,并在不降低整个应用程序复杂性的情况下工作。从那里解开它。如果它太复杂而无法进行单元测试。。。也许这是一个指标,你应该简化它并重构它。让它可测试。

我将把我以前的答案留给后代,但是。。。默认的Microsoft IoC提供程序非常简单,不支持Autofac的所有功能。您将无法从中获得参数化分辨率或自动生成工厂。

我将把以前的答案留给后代,但是。。。默认的Microsoft IoC提供程序非常简单,不支持Autofac的所有功能。您无法从中获得参数化分辨率或自动生成工厂。

以下是我必须做的: 修改的
ConfigureService
方法如下:

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);
    });
}
public void ConfigureServices(IServiceCollection services)
{
    IConfigurationInterceptor<T> GetConfigurationInterceptor<T>(ConfigurationInfo<T> info) where T : class 
    { 
        return new ConfigurationInterceptor<T>(info, services.GetService<IConfigurationProvider>(), Configuration);
    }

    services.AddSingletonConfiguration<IStaticDataConfiguration, StaticDataConfiguration>("someFeatureKey", GetConfigurationInterceptor);
 }
public static void AddSingletonConfiguration<TInterface, TImplementation>(this IServiceCollection services, 
    string featureName, Func<ConfigurationInfo<TImplementation>, IConfigurationInterceptor<TImplementation>> ic) where TImplementation : class, TInterface where TInterface : class
{ 
    var info = new ConfigurationInfo<TImplementation>(featureName, typeof(TInterface));
    var generator = new ProxyGenerator();
    services.AddSingleton(x =>
    {
        var icTemp = ic.Invoke(info);
        return (TInterface) generator.CreateInterfaceProxyWithoutTarget(info.ServiceType, icTemp);
    });
}
public static TInterface GetService<TInterface>(this IServiceCollection services) where TInterface : class
{ 
    var serviceProvider = services.BuildServiceProvider();
    return serviceProvider.GetRequiredService<TInterface>();
}
public void配置服务(IServiceCo)