Autofac Перехват не работает - PullRequest
0 голосов
/ 06 июня 2018

Я не могу заставить перехватить автофак.У меня есть следующие настройки в моем основном приложении .net:

// Создан регистратор: //

public class Logger : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        // Logging removed for now
        var watch = System.Diagnostics.Stopwatch.StartNew();  // Added break point here
        invocation.Proceed(); 
        watch.Stop();
        var executionTime = watch.ElapsedMilliseconds;
    }
}

// Класс создан: //

[Intercept(typeof(Logger))]
public class ServiceProxy: ServiceInterface
{
    public User GetUser(String username, String password)
    {
        var service = ServiceHelper.GetODataClaimService();
        var query = from a in service.Users
                            select a;
        var dsq = query.ToDataServiceQuery<User>();
        var result = dsq.ToListSync<User>();
        var user = result.FirstOrDefault();
        return user;
    }
}

// Интерфейс создан: //

public interface ServiceInterface
{
    User GetUser(String username, String password);
}

// Конфигурация перехвата //

public class Interceptor
{
    public static void Configure()
    {
        var builder = new ContainerBuilder();
        builder.Register(a => new Logger());
        builder.RegisterType<ServiceProxy>().As<ServiceInterface>().EnableInterfaceInterceptors().InterceptedBy(typeof(Logger));  // Tried removing intercepted by
        var container = builder.Build();
        var worker = container.Resolve<ServiceInterface>();
        builder.Build()
    }
}

Я установил точку останова в логгере, чтобы посмотреть, попадет ли он когда-либо в этот блок кода.Это никогда не делает.Что мне здесь не хватает?Я пробовал довольно много конфигураций, но, похоже, ничего не работает.Кроме того - метод Configure вызывается из запуска приложения.

Пожалуйста, сообщите.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

После того, как я опубликовал это, я понял, что во всех примерах в Интернете просто показано, как создается создатель и непосредственно выполняется метод.Я предполагал, что произошел перехват, похожий на тот, что был у ContextBoundedObjects / Remote Services, но это не так.Чтобы заставить это работать, мне пришлось использовать инъекцию зависимостей, чтобы внедрить ServiceInterface в конструктор моего класса.Фактически, строитель перехватил это и передал в Castle.Proxies.ServiceInterfaceProxy.

public class LoginController : Controller
{
    ServiceInterface proxy;

    public LoginController(ServiceInterface _proxy)
    {
        proxy = _proxy;
    }
}

Для этого потребовалось несколько дополнительных вещей, которых не было в примерах, которые я нашел в Интернете:

  1. Включение внедрения зависимостей Autofac

    с использованием Autofac.Extensions.DependencyInjection;

  2. Убедитесь, что Autofac включен в WebHostBuilder

     public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .ConfigureServices(services => services.AddAutofac())
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();
            host.Run();
        }
    }
    
  3. В настройках служб необходимо изменить, чтобы вернуть IServiceProvider

  4. При настройке компоновщика убедитесь, что компоновщик. Заполнение (услуги) включено

    public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
            services.AddKendo();
            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(Convert.ToInt32(Configuration["SessionTimeout"]));
                options.Cookie.HttpOnly = true;
            });
            return ConfigureProvider(services);
        }
    
        public IServiceProvider ConfigureProvider(IServiceCollection services)
        {
            var builder = new ContainerBuilder();
            builder.Populate(services);
            builder.Register(a => new LogInterception());
            builder.Register(a => new CircuitInterception());
            builder.RegisterType<ServiceProxy>().As<ServiceInterface>().EnableInterfaceInterceptors();
            Container = builder.Build();
            return new AutofacServiceProvider(this.Container);
        }
    
0 голосов
/ 06 июня 2018

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

Однако мне пришлось сделать три изменения, чтобы опробовать его.

  1. Я переключил метод ServiceInterface.GetUser, чтобы просто вернуть строку.У меня нет ваших объектов данных или чего-то еще.Я бы порекомендовал удалить этот материал из репродукции в вопросе, если он не важен для общего вопроса.
  2. Я удалил InterceptedBy(typeof(Logger)).Это не нужно для атрибутов, хотя я вижу комментарий, в котором говорится, что вы пытались это сделать.
  3. Я удалил дубликат builder.Build() из метода Interceptor.Configure().Это на самом деле вызовет исключение при попытке построить контейнер во второй раз.

Элемент № 3 касается меня, поскольку это означает, что в репро потенциально могут отсутствовать некоторые вещи, вызывающие проблему (и, возможно, выне пробовали репродукцию до публикации?).

В любом случае, вот полностью работающее консольное приложение, использующее ваш код:

    using Autofac;
    using Autofac.Extras.DynamicProxy;
    using Castle.DynamicProxy;
    using System;

    namespace InterfaceInterception
    {
        class Program
        {
            static void Main(string[] args)
            {
                var builder = new ContainerBuilder();
                builder.Register(a => new Logger());
                builder.RegisterType<ServiceProxy>().As<ServiceInterface>().EnableInterfaceInterceptors();
                var container = builder.Build();
                var worker = container.Resolve<ServiceInterface>();
                Console.WriteLine(worker.GetUser("", ""));
                Console.ReadKey();
            }
        }

        public class Logger : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                var watch = System.Diagnostics.Stopwatch.StartNew();
                invocation.Proceed();
                watch.Stop();
                var executionTime = watch.ElapsedMilliseconds;
                Console.WriteLine("Execution time: {0}", executionTime);
            }
        }

        [Intercept(typeof(Logger))]
        public class ServiceProxy : ServiceInterface
        {
            public string GetUser(String username, String password)
            {
                return "a";
            }
        }

        public interface ServiceInterface
        {
            string GetUser(String username, String password);
        }
    }

Вывод на консоль будет выглядеть следующим образом:

Execution time: 1
a

Вы можете установить точку останова в перехватчике, и она будет поражена.Вывод консоли показывает, что его тоже ударили.Итак ... что-то еще происходит, возможно, в коде вашего приложения, что вызывает проблемы, которые вы видите.Репродукция здесь выглядит [в основном] хорошо.

...