【问题标题】:service fabric asp .net core IoC error : cannot be dynamically proxied服务结构 asp .net 核心 IoC 错误:无法动态代理
【发布时间】:2018-07-25 08:57:58
【问题描述】:

我正在尝试将一些 IoC 放入我的 api 并不断收到此错误:

类型 Inovatic.SF.Windows.Facade.Facade 不能被动态代理。服务类型不能被密封并且需要对 DynamicProxyGenAssembly2 程序集可见。这可以通过将类型设为公共或将 InternalsVisibleToAttribute 添加到包含该类型的程序集来实现。例如[程序集:InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)]

program.cs:
//[assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)]
namespace Inovatic.SF.Windows.Facade
{
internal static class Program
{
    /// <summary>
    /// This is the entry point of the service host process.
    /// </summary>
    private static void Main()
    {
        try
        {
            var builder = new ContainerBuilder();
            builder.RegisterModule(new GlobalAutofacModule());
            builder.RegisterServiceFabricSupport();
            builder.RegisterStatelessService<Facade>("Inovatic.SF.Windows.FacadeType");

            using (builder.Build())
            {
                ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Facade).Name);
                Thread.Sleep(Timeout.Infinite);
            }
        }
        catch (Exception e)
        {
            ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
            throw;
        }
    }
}

public class GlobalAutofacModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<ConfigSettings>();
        builder.RegisterType<PaymentRepository>().As<IPaymentRepository>();
    }
}

}

我试过把这个(但不确定应该放在哪里):

[程序集:InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)]

并且还尝试将 Program 类标记为公开,但这似乎不起作用

编辑:

namespace Inovatic.SF.Windows.Facade
{
internal sealed class Facade : StatelessService
{
    public Facade(StatelessServiceContext context)
        : base(context)
    { 
        var telemetryConfig = TelemetryConfiguration.Active;
        telemetryConfig.InstrumentationKey = Environment.GetEnvironmentVariable("ApplicationInsightsKey");
        FabricTelemetryInitializerExtension.SetServiceCallContext(context);
    }

    /// <summary>
    /// Optional override to create listeners (like tcp, http) for this service instance.
    /// </summary>
    /// <returns>The collection of listeners.</returns>
    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        var endpoints = Context.CodePackageActivationContext.GetEndpoints()
            .Where(endpoint => endpoint.Protocol == EndpointProtocol.Http 
            || endpoint.Protocol == EndpointProtocol.Https);

        return endpoints.Select(endpoint => new ServiceInstanceListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, endpoint.Name, (url, listener) =>
            {
                ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                return new WebHostBuilder()
                    .UseKestrel(options =>
                    {
                        if (endpoint.Protocol == EndpointProtocol.Http)
                            options.Listen(IPAddress.Any, endpoint.Port);
                        else if (endpoint.Protocol == EndpointProtocol.Https)
                            options.Listen(IPAddress.Any, endpoint.Port,
                                listenOptions => listenOptions.UseHttps(Certificates.GetCertificateFromLocalStore(
                                        Environment.GetEnvironmentVariable("ClusterCertifThumbprint"))));
                    })
                    .ConfigureServices(
                        services =>
                        {
                            services
                                .AddSingleton(new ConfigSettings())
                                .AddSingleton(serviceContext)
                                .AddSingleton(new HttpClient())
                                .AddSingleton(new FabricClient());
                        })
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseStartup<Startup>()
                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                    .UseEnvironment(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))
                    .UseUrls(url)
                    .UseApplicationInsights()
                    .Build();
            }), endpoint.Name));
    }
}

}

【问题讨论】:

  • 您需要发布您的服务的代码。不是program.cs
  • 我不确定其他部分会有所帮助,您需要查看哪些具体内容?
  • Inovatic.SF.Windows.Facade.Facade
  • 这是错误信息的第一个奇怪的地方,我有 Inovatic.SF.Windows.Facade 但没有 Inovatic.SF.Windows.Facade.Facade
  • 所以让我直截了当地说:在命名空间namespace Inovatic.SF.Windows.Facade 中没有类Facade?你能发布你确实拥有的Facade的完整代码(包括命名空间)吗?

标签: azure asp.net-core-2.0 autofac azure-service-fabric


【解决方案1】:

您必须公开Facade 类并删除sealed 关键字(因为autofac 创建了一个继承自您的类的代理类。如果它是密封的,则禁止)。

所以改变

internal sealed class Facade : StatelessService

public class Facade : StatelessService

那你就不需要这个了

[assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)]

【讨论】:

  • 这不会带来任何安全问题吗?
  • 为什么?将类型设为公共仅允许依赖于该程序集的其他程序集使用此类。但这在你的控制之下。我们在谈论什么样的安全问题?如果您是这样想的,它不会神奇地从互联网上公开这项服务。
  • 抱歉耽搁了,改用 public seal class Facade 或 public class Facade ,显然服务不健康...
  • 没关系,但“密封”仍然需要移除
  • 是的,这是因为 autofac 创建了一个从您的类继承的代理类。如果是密封的,那是禁止的。我会相应地更新我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 2022-06-28
相关资源
最近更新 更多