按属性划分C#unity拦截

有没有办法在C#unity中如何使用属性拦截并将对象注册代码保存在XML文件中(如app.config)? 如果是的话,你能为我提供代码,这样的注册应该怎么样? 我做了很多解决方法,但没有找到解决此问题的方法。

我假设你的意思是使用自定义属性来指示拦截哪些方法。 您可以使用策略注入来使用XML配置实现拦截。

首先,让我们定义一个自定义属性:

[AttributeUsage(AttributeTargets.Method)] public class MyInterceptionAttribute : Attribute { } 

接下来,我们可以创建一个ICallHandler来执行一些拦截工作。 这个实现只会在方法之前和之后执行Console.WriteLine:

 public class MyLoggingCallHandler : ICallHandler { IMethodReturn ICallHandler.Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { Console.WriteLine("Invoking " + input.MethodBase.Name); IMethodReturn result = getNext()(input, getNext); Console.WriteLine("Done Invoke"); return result; } int ICallHandler.Order { get; set; } } 

接下来让我们假设我们有一些接口和实现:

 public interface IMyClass { void Do(); void DoAgain(); } public class MyClass : IMyClass { [MyInterception] public void Do() { Console.WriteLine("Do!"); } public void DoAgain() { Console.WriteLine("Do Again!"); } } 

请注意,我已将自定义属性MyInterception仅应用于Do方法,但未应用于DoAgain方法。 我们将拦截对Do方法的所有调用。

接下来,我们创建配置以定义策略,配置匹配规则并将类型与拦截器一起注册:

    

我们还需要一个类型转换器来将自定义属性的字符串表示转换为正确的类型:

 public class AssemblyQualifiedTypeNameConverter : ConfigurationConverterBase { public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (value != null) { Type typeValue = value as Type; if (typeValue == null) { throw new ArgumentException("Cannot convert type", typeof(Type).Name); } if (typeValue != null) return (typeValue).AssemblyQualifiedName; } return null; } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { string stringValue = (string)value; if (!string.IsNullOrEmpty(stringValue)) { Type result = Type.GetType(stringValue, false); if (result == null) { throw new ArgumentException("Invalid type", "value"); } return result; } return null; } } 

完成所有设置后,我们可以创建一个容器并加载配置:

 var container = new UnityContainer().LoadConfiguration(); var myClass = container.Resolve(); myClass.Do(); myClass.DoAgain(); 

输出将是:

 Invoking Do Do! Done Invoke Do Again! 

显示第一种方法被截获而第二种方法没有截获。

这是一个老问题,但对我来说真的很有用,所以我将添加统一配置的C#版本。

 container.Configure() .AddPolicy("LoggingPolicy") .AddMatchingRule(new CustomAttributeMatchingRule(typeof(MyInterceptionAttribute), false)) .AddCallHandler(); container.RegisterType(new Interceptor(), new InterceptionBehavior());