If you're not familiar with this problem, try creating two or more classes that require each other's services: for instance an AccountService and a LoanService. Then try to inject the dependencies at runtime using a dependency-injection framework like Unity. The iterative nature of this sort of lookup causes a stack overflow.
There are ways to avoid this problem which i won't be talking about in this post. However, what I will be talking about is reducing the scope of a service to the point of it being a single method, a delegate.
Before reading further and if you haven't, take a look at the differences between interfaces and delegates in this MSDN article. (if the link is stale, search for delegate instead of interfaces in MSDN):
http://msdn.microsoft.com/en-us/library/ms173173.aspx
If I define my services in terms of delegates, I can implement them in any grouping that I want: I can implement each delegate in a dedicated class, bundle all into one class, or try to logically group them in corresponding classes.
You can go from coarse-grained (all ine one class) to the finest-grained grouping (each delegate in its own class) of program logic.
Let's get started. First I tried Unity as is and susprisingly it handled delegates with no problem.
To register delegate implementations, register them as "instances". Here's an example:
1. Declare the delegate
public delegate void VoidMethod();
2. Implement it somewhere:
public class MethodImpl
{
public void VoidMethodImpl()
{
MarkAsCalled("VoidMethodImpl");
Trace.WriteLine("VoidMethodImpl was called");
}
}
3. Register the implementation for the delegate type:
DelegateTestSupport.MethodImpl impl =
new DelegateTestSupport.MethodImpl();
container.RegisterInstance<VoidMethod>(impl.VoidMethodImpl);
4. Try to resolve the delegate and call it:
container.Resolve<VoidMethod>()();
It works perfectly. It makes you gain a new sense of appreciation for the language and also the work put in Unity.
You could also implement the delegates on the fly, using anonymous delegates or Lambda expressions:
container.RegisterInstance<VoidMethod>(
delegate()
{
Debug.WriteLine("anonymous delegate was called");
}
);
So the next optional step is to try to intercept calls to your delegates using Unity Interception extension. You'd probably have some common, cross-cutting concerns that you have encapsulated and now ready to apply to qualified delegates.
Here's where I got stopped. None of the interceptors in Unity could intercept a call to delegates registered like above. At least I could'nt get them to work.
So how would one go about intercepting delegates registered in a container? That's discussed in the next post.
No comments:
Post a Comment