我无法通过autofac进行拦截。我的.net核心应用程序中有以下设置:
// Logger created://
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方法..
请告知。
答案 0 :(得分:0)
使用您发布的代码,我无法重现您描述的问题。拦截器被击中,一切正常。
但是,我必须进行三次更改才能尝试。
ServiceInterface.GetUser
方法切换为只返回一个字符串。我没有你的数据对象或任何东西。如果对整个问题不重要,我建议从问题中删除那些东西。InterceptedBy(typeof(Logger))
。属性不需要这些,但我确实看到了你试过的评论。builder.Build()
方法中删除了重复的Interceptor.Configure()
。这实际上会在尝试第二次构建容器时引发异常。项目#3关注我,因为这意味着repro可能会遗漏一些导致问题的东西(也许你在发布之前没有尝试过repro?)。
无论如何,这是一个使用您的代码的完全正常的控制台应用程序:
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
你可以在拦截器中放置一个断点,它会受到攻击。控制台输出也显示它被击中。所以...还有其他事情正在发生,可能在您的应用代码中,这会导致您看到的问题。这里的复制品看起来[基本上]很好。
答案 1 :(得分:0)
我在发布之后意识到,网上的所有示例都只显示正在创建的构建器并直接执行方法。我假设有类似于ContextBoundedObjects / Remote Services的拦截,但事实并非如此。为了使其工作,我不得不使用依赖注入将ServiceInterface注入到我的类的构造函数中。实际上,构建器拦截了这个并传入了Castle.Proxies.ServiceInterfaceProxy。
public class LoginController : Controller
{
ServiceInterface proxy;
public LoginController(ServiceInterface _proxy)
{
proxy = _proxy;
}
}
这需要一些我在网上找到的示例中没有的其他内容:
包含Autofac依赖注入
使用Autofac.Extensions.DependencyInjection;
确保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();
}
}
配置服务必须更改才能返回IServiceProvider
设置构建器时,请确保包含builder.Populate(services)
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);
}