我无法通过autofac截获对我班级的电话。 我已经修改了Program.cs文件,使其包含Autofac。 我已经修改了Startup.cs文件,使其包含ConfigureContainer。 调用该方法时,它将绕过Loggable属性中的Intercept方法。缺少什么?
public class Program
{
public static void Main(string[] args)
{
var host = WebHost.CreateDefaultBuilder(args)
.UseKestrel()
.ConfigureServices(services => services.AddAutofac())
.UseStartup<Startup>().Build();
host.Run();
}
}
public class Startup
{
public IConfiguration Configuration { get; private set; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureContainer(ContainerBuilder builder)
{
var helper = new StartupHelper();
helper.Configure(builder, Configuration);
}
public void ConfigureServices(IServiceCollection services)
{
services.AddOData();
services.AddMvc()
.AddControllersAsServices();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
var name = "OData";
var prefix = "OData";
var builder = new ODataConventionModelBuilder();
builder.EntitySet<DistributorParent>("DistributorParents")
.EntityType
.HasKey(a => a.DistparKey);
app.UseMvc(routebuilder =>
{
routebuilder.Select()
.Expand()
.Filter()
.OrderBy()
.MaxTop(null)
.Count();
routebuilder.MapODataServiceRoute(name, prefix, builder.GetEdmModel());
});
}
}
public class StartupHelper
{
public ContainerBuilder Configure(ContainerBuilder builder, IConfiguration configuration = null)
{
builder.Register(a => configuration);
builder.Register(a => new Loggable());
builder.RegisterType<DistributorParentBusiness>()
.As<IBusiness<DistributorParent>>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(Loggable));
return builder;
}
}
[Loggable]
public class DistributorParentBusiness : IBusiness<DistributorParent>
{
private IConfiguration Configuration;
private String Connection;
public DistributorParentBusiness(IConfiguration configuration)
{
Configuration = configuration;
Connection = Configuration.GetConnectionString("CorpdbConnection");
}
public virtual DistributorParent Get(Int32 key)
{
var context = new CorpdbContext(Connection);
var query = from a in context.DistributorParent
where a.DistparKey == key
select a;
return query.FirstOrDefault();
}
public virtual IQueryable<DistributorParent> Get()
{
var context = new CorpdbContext(Connection);
var query = from a in context.DistributorParent
select a;
return query;
}
}
答案 0 :(得分:0)
这里有很多要解压的内容,而并非100%所需的信息。我会给您一些要看的东西,其中之一应该有所帮助。
您正在使用接口拦截器,因此将仅拦截接口方法。我不知道IBusiness<T>
接口的外观(部分丢失的信息),所以我不知道不知道DistributorParentBusiness
中的哪些方法是接口的一部分。如果您在界面中调用不是 的方法,则该方法将不会被拦截。
Loggable
看起来像一个属性,但是需要实现IInterceptor
。我不知道Loggable
是什么样,但是它必须实现{{1 }}(如果您正在使用它进行拦截)。它根本不是属性,这让我感到奇怪。它似乎没有做任何事情,因为它是以属性形式应用的。
The Autofac docs have examples of setting up interface injection.如果使用IInterceptor
,则不使用属性。如果要使用属性,则必须为InterceptedBy(typeof(T))
,如果要使用属性,则不要使用[Intercept(typeof(Logger))]
。是/或,并且拦截器永远不是属性本身。
控制器是服务,但我不知道InterceptedBy(typeof(T))
在哪里使用。同样,缺少信息。如果将其注入控制器中,它应该可以工作。我认为,如果您不添加controllers-as-services,它甚至应该可以工作。
您在其中计算所有路由的路由生成器调用很奇怪。不,这与问题无关,但是...正在对它们进行计数而不使用值?什么...呃...发生了什么事?
我要尝试的是为自己创建一个单元测试级别的副本。也就是说,仅在可以参与的单元测试中创建一个小的副本。确保首先正确连接接口拦截器。做一个超级简单,基本上是空的IBusiness<DistributorParent>
实现;创建一个具有接口拦截功能的容器;手动解决IBusiness<DistributorParent>
;在拦截器中设置断点;调用您希望被截获的方法,并查看断点是否被击中。或创建一个始终返回固定的已知值的拦截器,并在测试中使用该拦截器(如果未遇到断点的话),有时诸如“ Just My Code”之类的设置可能最终导致某些内容被跳过。
要点是,如果以上所有内容均无法解决问题,请在单元测试表格中创建一个真正的最小复制品,并确保其有效。如果可以的话,将其扩大一点-也许您在repro中使用了其他拦截器就可以了;尝试使用实际的IBusiness<DistributorParent>
拦截器。它仍然有效吗?如果没有,也许是问题的拦截器。如果是这样,请扩大范围。最终,您将使整个工作正常进行,或者发现不起作用的地方。
如果您确实以最小的复制量使整个工作正常进行,那么问题可能是您没有意识到的。例如,repro中的代码是否与真实系统中的代码完全相同?有什么不同?努力使repro代码接近真实代码,并查看何时停止工作。
不过,我认为最低再现确实是您的关键。
对以后问题的建议-在创建问题代码时,请尝试使其成为我上面所述的用于故障排除的简单,微小的复制品。足以显示问题(并且可能由想要尝试的人进行编译),但仅此而已。
Loggable
和Loggable
。IBusiness<T>
调用中的路由配置不相关。app.UseMvc()
中的代码内联到StartupHelper
方法中,以使回答问题的人们更容易阅读和理解。答案 1 :(得分:0)
问题很傻。我是手动创建类,而不使用di。因此,这些方法不会被拦截。另外,原始设置试图拦截api控制器,并且这些方法不是虚拟的。只需进行少量配置更改即可注入IBusiness和voila,它确实有效...