Thanks in advance for your help! (Yes, there's a question at the bottom)
I'm using Unity 3.x Interception to perform AOP pre and post database connection and transaction activities. The database interceptor is always instantiated and the transaction interceptor is CustomAttributeMatchingRule based, both via InterfaceInterceptor. I have properties that are being set in my TransactionAttribute:
[Transaction(IsolationLevel.ReadUncommitted, NoRollbackFor = new[] { typeof(TestException) })]
as an example I'm using in my unit test. I would like to access them in my TransactionCallHandler class invoke method. I've seen examples saying
var transactionAttribute = input.MethodBase.GetCustomAttribute<TransactionAttribute>(false);
is the way to access this, yet my transaction var is null. My conclusion is the interception proxy class is being checked for the custom attribute and not the original concrete instance.
My work around for this is to reflect all the way back to the class level, dig through to figure out what the correct method is that's being intercepted and perform the get custom attribute from there.
var methods = input
.Target
.GetType()
.GetMethods()
.Where(m => m.Name == input.MethodBase.Name)
.Where(m => m.GetCustomAttribute<TransactionAttribute>(false) != null);
(There's about another 30 lines of code to ensure I'm not accessing the wrong method name if the method has overloads; hence the performance drag...)
So, after all that, my question is: Am I not performing the reflection correctly? Is there a bug in Unity I should report?
Here's my container definitions:
Container = new UnityContainer();
Container.AddNewExtension<Interception>();
Container.RegisterType<IMockUseDefaultConnectionString, MockUseDefaultConnectionString>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>(),
new InjectionConstructor(new DatabaseSettings()));
Container.RegisterType<IMockUseHardcodedConnectionString, MockUseHardCodedConnectionString>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>(),
new InjectionConstructor(new DatabaseSettings
{
ConnectionString = MockUseHardCodedConnectionString.ConnectionString
}));
/* IDatabaseSettings is not registered to manually control the settings being used */
var first = new InjectionProperty("Order", 1);
var second = new InjectionProperty("Order", 2);
Container
.Configure<Interception>()
.AddPolicy("DatabaseConnectionPolicy")
.AddMatchingRule<NamespaceMatchingRule>(new InjectionConstructor("MyNamespace.*", true))
.AddCallHandler<DatabaseConnectionCallHandler>(first);
Container
.Configure<Interception>()
.AddPolicy("TransactionPolicy")
.AddMatchingRule(new CustomAttributeMatchingRule(typeof(TransactionAttribute), inherited: false))
.AddCallHandler<TransactionCallHandler>(second);