为了让城堡温莎的拦截器拦截一个方法,该方法是否需要公开?
aop castle-windsor castle-dynamicproxy ioc-container interceptor
如何通过WCF频道发送Castle.Proxies.EntityProxy?
如何将代理设置为KnownType?
我试图想出一种方法(动态或实例)方法调用可以被动态代理拦截.我想将它作为c#扩展方法实现,但坚持如何为静态方法生成动态代理.
一些用法:
Repository.GetAll<T>().CacheForMinutes(10);
Repository.GetAll<T>().LogWhenErrorOccurs();
//or
var repo = new Repository();
repo.GetAll<T>().CacheForMinutes(10);
repo.GetAll<T>().LogWhenErrorOccurs();
Run Code Online (Sandbox Code Playgroud)
我对任何图书馆(linfu,castle.dynamic proxy 2等)开放.
谢谢!
我目前正在使用Castle DynamicProxy实现拦截器.我要求拦截器在我的服务层方法上获取一些自定义属性,但是invocation.Method.GetCustomAttributes什么都不返回.我可能做错什么?
截获方法:
[Transaction()]
[SecurityRole(AuthenticationRequired = false, Role = SystemRole.Unauthorised)]
public virtual void LoginUser(out SystemUser userToLogin, string username)
{
...
}
Run Code Online (Sandbox Code Playgroud)
拦截器:
// Checks that a security attribute has been defined
foreach (SecurityRoleAttribute role in invocation.Method.GetCustomAttributes(typeof(SecurityRoleAttribute), true))
{
if (!securityAttributeDefined)
securityAttributeDefined = true;
}
Run Code Online (Sandbox Code Playgroud)
我也尝试过:
Attribute.GetCustomAttribute(invocation.Method, typeof(SecurityRoleAttribute), true);
Run Code Online (Sandbox Code Playgroud)
更新:
可能是配置问题.配置代码如下:
InterceptorsInstaller:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<LoggingInterceptor>()
.Named("LoggingInterceptor"));
container.Register(
Component.For<SecurityInterceptor>()
.Named("SecurityInterceptor"));
container.Register(
Component.For<ValidationInterceptor>()
.Named("ValidationInterceptor"));
}
Run Code Online (Sandbox Code Playgroud)
的ServiceInstaller:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
string[] interceptors = {"LoggingInterceptor", …Run Code Online (Sandbox Code Playgroud) 代理对象并使用城堡动态代理拦截方法时,是否可以获取目标方法的返回值?我尝试过使用以下方法,
object result = invocation.GetConcreteMethod().Invoke(instance, null);
object result = invocation.GetConcreteMethodInvocationTarget().Invoke(instance, null);
Run Code Online (Sandbox Code Playgroud)
这会导致无限循环.我希望能够在调用Invocation.Proceed()之前获取原始目标方法的返回值.
编辑 - Fyi我通过使用Activator.CreateInstance让它工作,但我想知道是否有更简洁的方法来实现等效:
object instance = Activator.CreateInstance(invocation.TargetType);
invocation.MethodInvocationTarget.Invoke(instance, invocation.Arguments);
Run Code Online (Sandbox Code Playgroud)
问题是这只是原始对象的一个新的非代理实例,而我想要原始的非代理实例本身.
我有一些简单的DTO类,如:
[XmlType]
class Person : AbstractResource
{
[XmlElement("name")]
public virtual string FirstName { get; set; }
public virtual string Nickname { get { return "Mister cool"; } }
}
class SpecialPerson : Person
{
public override string NickName { get { return FirstName; } }
}
Run Code Online (Sandbox Code Playgroud)
在我的代码中,我从XML文件中反序列化Person/SpecialPerson对象的列表,然后尝试使用CreateClassProxyWithTarget将它们全部包装在代理实例中.出于某种原因,对于任何SpecialPerson代理,FirstName始终为null并且NickName为null,但对于任何Person代理,返回"Mister cool".
我进入调试器并查看底层包装对象,它具有所有正确的值.我也注意不要拦截FirstName或Nickname.我希望代理只是简单地调用包装对象,在某些情况下它会[1]但是对于大多数情况它不会.我究竟做错了什么?
[1]在我的拦截器代码中,我通过反射设置了包装对象的一些属性,并且这些属性正确显示.但我不明白为什么这些属性会从底层对象中读取,但其他属性则不会.这几乎就像任何截获的属性在调用Invoke时总是会调用包装对象,但是对于任何方法,你都没有为ShouldInterceptMethod返回false.但这对我来说没有任何意义,如果我说不拦截一个包装对象上的方法应该采取什么其他可能的操作,而只是使用包装对象的属性?
我正在学习Castle Windsor和WCF的依赖注入和拦截,我想检查一个截获的方法是否有自定义属性(LogAttribute).
(我的例子基于这个答案:https://stackoverflow.com/a/2593091)
服务合约 :
[ServiceContract]
public interface IOrderService
{
[OperationContract]
Order GetOrder(int orderId);
}
[DataContract]
public class Order
{
[DataMember]
public string Id { get; set; }
// [...]
}
Run Code Online (Sandbox Code Playgroud)
服务实施:
public class OrderService : IOrderService
{
private readonly IDatabase _database;
public OrderService(IDatabase database)
{
_database = database;
}
[Log] // <- my custom attribute
public Order GetOrder(int orderId)
{
return _database.GetOrder(orderId);
}
}
public class LogAttribute : Attribute
{ }
Run Code Online (Sandbox Code Playgroud)
简单的数据访问层:
public interface IDatabase …Run Code Online (Sandbox Code Playgroud) c# wcf dependency-injection castle-windsor castle-dynamicproxy
我不知何故在兜圈子......我尝试使用 Castle Dynamic Proxy 创建一个带有目标的接口代理。代理应该
InterceptedException如果调用抛出一个 则抛出 new InvalidOperationException。e如果调用抛出另一个异常,则抛出e。换句话说,拦截器应该捕获并转换特定的异常类型,而不是在所有其他情况下拦截。
我让这个适用于同步方法。但是,我需要返回任务的异步方法具有相同的行为。
我尝试向返回的任务添加延续并检查IsFaulted(Exception类似于此答案。这适用于 return 的方法Task,但不适用于返回的方法,Task<T>因为我的延续是类型Task(并且我不知道T拦截器中有什么) 。
public class ConvertNotFoundInterceptorTest
{
[Fact]
public void Non_throwing_func_returns_a_result()
{
Assert.Equal(43, RunTest(i => i + 1));
}
[Fact]
public void InvalidOperationExceptions_are_converted_to_IndexOutOfRangeExceptions()
{
var exception = Assert.Throws<AggregateException>(() => RunTest(i => { throw new InvalidOperationException("ugh"); }));
Assert.True(exception.InnerException is IndexOutOfRangeException);
}
[Fact] …Run Code Online (Sandbox Code Playgroud) 我正在使用Moq框架进行模拟.我发现Equals覆盖不能按预期工作的问题.似乎动态对象中必须有一个总是返回false的覆盖.这是一些示例代码.我正在使用nuget的Moq版本4.2.1507.0118.
public class B
{
public override bool Equals(object obj)
{
return base.Equals(obj);
}
}
class Program
{
static void Main(string[] args)
{
var a = new Moq.Mock<B>().Object;
var b = a;
bool equalsOperator = a == b; //returns true
bool referenceEquals = object.ReferenceEquals(a, b); //returns true
bool equals_b = a.Equals(b); //returns false
bool equals_a = a.Equals(a); //returns false
}
}
Run Code Online (Sandbox Code Playgroud)
另一个有趣的事情是,如果断点放在Equals覆盖上,它永远不会被击中.Moq框架中是否存在错误,或者是否存在我做错的事情?
我有许多 AOP 库,它们使用 Castle DynamicProxy 和 Autofac DI 容器进行日志记录、审计、事务控制等。
我想知道是否有办法使用默认的 .NET Core DI 容器来声明拦截器。拥有这种灵活性会很好,因为许多 .NET Core 项目不使用 Autofac。
aop dependency-injection castle-dynamicproxy autofac .net-core