Service Fabric asp .net core IoC error: не может быть динамически проксирован

Я пытаюсь добавить IoC в свой api и продолжаю получать эту ошибку:

The type Inovatic.SF.Windows.Facade.Facade cannot be dynamically proxied. Service types must not be sealed and need to be visible to the DynamicProxyGenAssembly2 assembly. This can be achieved by making the type public or adding the InternalsVisibleToAttribute to the assembly containing the type. e.g. [assembly: 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>();
    }
}

}

Я попытался поставить это (но не уверен, куда он должен идти):

[assembly: 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

Peter Bons 25.07.2018 11:01

Я не уверен, что еще может помочь, что-то конкретное, что вам нужно увидеть?

Xav Sc 25.07.2018 11:05

Inovatic.SF.Windows.Facade.Facade

Peter Bons 25.07.2018 11:06

это первая странность сообщения об ошибке, у меня Inovatic.SF.Windows.Facade но не Inovatic.SF.Windows.Facade.Facade

Xav Sc 25.07.2018 11:08

Итак, позвольте мне сказать прямо: у вас нет класса Facade в пространстве имен namespace Inovatic.SF.Windows.Facade? Можете ли вы опубликовать полный код (включая пространства имен) Facade, который у вас есть делать?

Peter Bons 25.07.2018 11:10

Простите, недоразумение, основной пост отредактирован

Xav Sc 25.07.2018 11:11
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
1
6
197
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны сделать класс Facade общедоступным и удалить ключевое слово sealed (поскольку autofac создает прокси-класс, который наследуется от вашего класса. Если он запечатан, это запрещено).

Так что измени

internal sealed class Facade : StatelessService

к

public class Facade : StatelessService

Тогда тебе это больше не нужно

[assembly: InternalsVisibleTo(InternalsVisible.ToDynamicProxyGenAssembly2)]

это не повлечет за собой никаких проблем с безопасностью?

Xav Sc 25.07.2018 11:14

Почему? делая тип общедоступным, только другие сборки, которые зависят от этой сборки, могут использовать этот класс. Но это под вашим контролем. О каких проблемах безопасности мы говорим? Это не волшебным образом сделает эту услугу общедоступной из Интернета, если вы так думаете.

Peter Bons 25.07.2018 11:15

Извините за задержку, переключение на публичный закрытый класс Facade или публичный класс Facade делает службу, по-видимому, нездоровой ...

Xav Sc 25.07.2018 11:55

Да ладно, работает, а вот "пломбу" все равно нужно удалить

Xav Sc 25.07.2018 12:05

да, это потому, что autofac создает прокси-класс, который наследуется от вашего класса. Если он запломбирован, это запрещено. Я обновлю свой ответ соответственно

Peter Bons 25.07.2018 13:26

Другие вопросы по теме