Not to mention, this is a fairly a short list and there can be many more scenarios where we need to compose a relationship type. However, going further we will be talking about the most commonly used composed relationship Func<Owned<T>>.
Using Func<Owned<T>>
Consider a SwitchUserView class (say, windows form) that accepts a dependency of IPrintView to render some sort of unique view to its use as requested. Now, there are two important things:
- The user never requests the view
In such a case, injecting the view as a direct dependency is not an option. In fact, the decision is to be made at runtime, and therefore we need a Func<T>.
- The view object is held for too long
Think of a scenario when the user closes the IPrintView and stays on the parent form, trying other available views. The point is, if the view is resolved in the same lifetime scope as that of its parent form, the view object might be held for too long in the memory before it is released. And, so will be its dependencies, if any. Therefore we need to control the lifetime of the view using Owned<T>.
Satisfying either of the problems is not enough. Therefore, we need a composed relationship type Func<Owned<IPrintView>>, which solves both of our problems. The code below shows the implementation:
- public interface IPrintView
- {
- void Show();
- }
-
- public class SwitchUserView
- {
- private Func<Owned<IPrintView>> _printViewCreator;
- public SwitchUserView(Func<Owned<IPrintView>> printViewCreator)
- {
- _printViewCreator = printViewCreator;
- }
-
- public void SwitchToPrintView()
- {
- using(var printView = _printViewCreator())
- {
- printView.Value.Show();
- }
- }
- }
It's not always the case that we need to compose relationship types, but yes they are used quite enough.
Register the Components
The registration of the components with the container will be no different than what we have seen in earlier posts.
- var builder = new ContainerBuilder();
-
- builder.RegisterType<SwitchUserView>().AsSelf();
- builder.RegisterType<PrintView>().As<IPrintView>();
-
-
Summary
While Func<Owned<T>> might not suit everyone's requirement, the whole intention here is to see how we can compose different relations that best suit our situation. I hope this article helps one and all to get a basic understanding of the topic, yet makes you confident enough. All you need is to come up with different scenarios and see which relation would be best, or if you don't need to compose a relationship at all.
Related Articles