问题
I have an application that has a base class and derived classes from it with each implementation class having it's own interface. I would like to use Unity's interception for exception handling on derived types of a base class.
I am new to interception so I don't know all the quirks. As far as I know, I have to register interception with each implementation resolve. The point is that all of my implementations have a base class, so I thought that I could skip the redundancy and set the interception on base class only, which would fire on each implementation class.
This is my setting:
public class NotificationViewModel
{
// some properties
}
public class CompanyViewModel : NotificationViewmodel
{
// some properties
}
public class BaseService
{
}
public interface ICompanyService
{
public NotificationViewModel Test();
}
public class CompanyService : BaseService, ICompanyService
{
public CompanyViewModel Test()
{
// call exception
}
}
public class TestUnityContainer : UnityContainer
{
public IUnityContainer RegisterComponents()
{
this
.AddNewExtension<Interception>()
.RegisterType<ICompanyService, CompanyService>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<TestInterceptionBehavior>());
return this;
}
}
public class TestInterceptionBehavior : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return new[] { typeof( INotifyPropertyChanged ) };
}
public IMethodReturn Invoke( IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext )
{
IMethodReturn result = getNext()( input, getNext );
if( result.Exception != null && result.Exception is TestException )
{
object obj = Activator.CreateInstance( ( ( System.Reflection.MethodInfo )input.MethodBase ).ReturnType );
NotificationViewModel not = ( NotificationViewModel )obj;
// do something with view model
result.ReturnValue = obj;
result.Exception = null;
}
return result;
}
public bool WillExecute
{
get { return true; }
}
}
This works fine, but I would like to have something like this in TestUnityContainer
public class TestUnityContainer : UnityContainer
{
public IUnityContainer RegisterComponents()
{
this
.AddNewExtension<Interception>()
.RegisterType<BaseService>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<TestInterceptionBehavior>() );
.RegisterType<ICompanyService, CompanyService>();
return this;
}
}
I will have many more service classes inheriting from base service and I thought this would save me a lot of time because they all have the same interception behavior.
Is this possible with Unity and how? If some minor corrections to the model are necessary, I am open for them, as long as they are minor.
回答1:
I would suggest you look at Policy Injection in Unity rather than manually applying behaviours on types. With policies you must:-
- Create an class that implements ICallHandler (basically a cut down IInterceptionBehavior) - this would be your exception handler behavior.
- Create a policy that has "matching rules" - in your case, a policy that uses your CallHandler for any registered types that implement BaseService or similar.
- You will still have to register all your services into Unity, but now pass in the Interceptor and InterceptionBehavior. If you have many services, I would suggest looking at something like my Unity Automapper which will simplify both registration and having to mess around with interception behaviors.
来源:https://stackoverflow.com/questions/16130106/microsoft-unity-base-class-interception