You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/DryIoc.Docs/RegisterResolve.cs
+53-28
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,8 @@
17
17
- [RegisterMany](#registermany)
18
18
- [RegisterMapping](#registermapping)
19
19
- [RegisterDelegate](#registerdelegate)
20
-
- [Will not detect recursive dependencies](#will-not-detect-recursive-dependencies)
20
+
- [The cure - RegisterDelegate with the dependency parameters](#the-cure---registerdelegate-with-the-dependency-parameters)
21
+
- [RegisterDelegate is harder to use when types are not known](#registerdelegate-is-harder-to-use-when-types-are-not-known)
21
22
- [RegisterInstance](#registerinstance)
22
23
- [RegisterInitializer](#registerinitializer)
23
24
- [RegisterPlaceholder](#registerplaceholder)
@@ -606,9 +607,9 @@ public void Example()
606
607
607
608
## RegisterMapping
608
609
609
-
`RegisterMapping` allows to map new service to already registered service and its implementation.
610
+
`RegisterMapping` allows to map a new service to the already registered service and its implementation.
610
611
611
-
For example you have a singleton implementation which can be accessed via two different facades / services:
612
+
For example you have a singleton implementation which may be accessed via two different facades / services:
612
613
```cs md*/
613
614
classRegister_mapping
614
615
{
@@ -632,7 +633,7 @@ public void Example()
632
633
}/*md
633
634
```
634
635
635
-
This same result maybe achieved via `RegisterMany`:
636
+
The same result may be achieved via the `RegisterMany`:
636
637
637
638
```cs md*/
638
639
classRegister_mapping_with_RegisterMany
@@ -684,8 +685,8 @@ internal class CheerfulService : IService
684
685
}/*md
685
686
```
686
687
687
-
The `IResolverContext resolverContext` delegate parameter was not used in example above.
688
-
Actually, it could be used to resolve any additional dependencies required for service creation and initialization:
688
+
The `IResolverContext resolverContext` delegate parameter was not used in the example above.
689
+
Actually, it could be used to resolve any additional dependencies required for the service creation and initialization:
689
690
690
691
```cs md*/
691
692
classRegister_delegate_with_resolved_dependencies
@@ -725,10 +726,54 @@ public CheerfulService(GreetingsProvider greetingsProvider)
725
726
Though powerful, registering delegate may lead to the problems:
726
727
727
728
1. Memory leaks by capturing variables into delegate closure and keeping them for a container lifetime.
728
-
2. Delegate is the black box for Container - which makes hard to find type mismatches or diagnose other potential problems.
729
+
2. Delegate is the black box for Container, mostly because it should use the `Resolve` call inside to resolve the dependency cutting of the object graph analysis, which makes it hard to find type mismatches or diagnose other potential problems. Among the un-catched problems are:
Therefore, try to use it only as a last resort. DryIoc has plenty of tools to cover for custom delegate in more effective way.
731
-
The ultimate alternative would be a [FactoryMethod](ConstructorSelection).
735
+
The alternative would be a [FactoryMethod](ConstructorSelection).
736
+
737
+
Another alternative would be the **RegisterDelegate with the dependency parameters introduced in DryIoc v4.3**. See below...
738
+
739
+
### The cure - RegisterDelegate with the dependency parameters
740
+
741
+
It solves the two problems mentioned in the [RegisterDelegate](#registerdelegate) above because
742
+
it **injects** the requested dependencies as a delegate arguments so there is no need in calling `Resolve` inside.
743
+
744
+
- The dependencies injection and their lifetime is controlled by container
745
+
- There is no black-box service location involved and both [Recursive Dependency](ErrorDetectionAndResolution#RecursiveDependencyDetected) and [Captive Dependency](ErrorDetectionAndResolution#using-validate-to-check-for-captive-dependency) problems are catched by container.
Copy file name to clipboardExpand all lines: docs/DryIoc.Docs/RegisterResolve.md
+52-28
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,8 @@
16
16
-[RegisterMany](#registermany)
17
17
-[RegisterMapping](#registermapping)
18
18
-[RegisterDelegate](#registerdelegate)
19
-
-[Will not detect recursive dependencies](#will-not-detect-recursive-dependencies)
19
+
-[The cure - RegisterDelegate with the dependency parameters](#the-cure---registerdelegate-with-the-dependency-parameters)
20
+
-[RegisterDelegate is harder to use when types are not known](#registerdelegate-is-harder-to-use-when-types-are-not-known)
20
21
-[RegisterInstance](#registerinstance)
21
22
-[RegisterInitializer](#registerinitializer)
22
23
-[RegisterPlaceholder](#registerplaceholder)
@@ -605,9 +606,9 @@ __Note:__ If you really need to register something from the list, you may regist
605
606
606
607
## RegisterMapping
607
608
608
-
`RegisterMapping` allows to map new service to already registered service and its implementation.
609
+
`RegisterMapping` allows to map a new service to the already registered service and its implementation.
609
610
610
-
For example you have a singleton implementation which can be accessed via two different facades / services:
611
+
For example you have a singleton implementation which may be accessed via two different facades / services:
611
612
```cs
612
613
classRegister_mapping
613
614
{
@@ -631,7 +632,7 @@ class Register_mapping
631
632
}
632
633
```
633
634
634
-
This same result maybe achieved via `RegisterMany`:
635
+
The same result may be achieved via the`RegisterMany`:
635
636
636
637
```cs
637
638
classRegister_mapping_with_RegisterMany
@@ -683,8 +684,8 @@ class Register_delegate
683
684
}
684
685
```
685
686
686
-
The `IResolverContext resolverContext` delegate parameter was not used in example above.
687
-
Actually, it could be used to resolve any additional dependencies required for service creation and initialization:
687
+
The `IResolverContext resolverContext` delegate parameter was not used in the example above.
688
+
Actually, it could be used to resolve any additional dependencies required for the service creation and initialization:
688
689
689
690
```cs
690
691
classRegister_delegate_with_resolved_dependencies
@@ -724,10 +725,53 @@ class Register_delegate_with_resolved_dependencies
724
725
Though powerful, registering delegate may lead to the problems:
725
726
726
727
1. Memory leaks by capturing variables into delegate closure and keeping them for a container lifetime.
727
-
2. Delegate is the black box for Container - which makes hard to find type mismatches or diagnose other potential problems.
728
+
2. Delegate is the black box for Container, mostly because it should use the `Resolve` call inside to resolve the dependency cutting of the object graph analysis, which makes it hard to find type mismatches or diagnose other potential problems. Among the un-catched problems are:
Therefore, try to use it only as a last resort. DryIoc has plenty of tools to cover for custom delegate in more effective way.
730
-
The ultimate alternative would be a [FactoryMethod](ConstructorSelection).
734
+
The alternative would be a [FactoryMethod](ConstructorSelection).
735
+
736
+
Another alternative would be the **RegisterDelegate with the dependency parameters introduced in DryIoc v4.3**. See below...
737
+
738
+
### The cure - RegisterDelegate with the dependency parameters
739
+
740
+
It solves the two problems mentioned in the [RegisterDelegate](#registerdelegate) above because
741
+
it **injects** the requested dependencies as a delegate arguments so there is no need in calling `Resolve` inside.
742
+
743
+
- The dependencies injection and their lifetime is controlled by container
744
+
- There is no black-box service location involved and both [Recursive Dependency](ErrorDetectionAndResolution#RecursiveDependencyDetected) and [Captive Dependency](ErrorDetectionAndResolution#using-validate-to-check-for-captive-dependency) problems are catched by container.
745
+
746
+
The example:
747
+
```cs
748
+
749
+
classRegister_delegate_with_parameters
750
+
{
751
+
[Test] publicvoidExample()
752
+
{
753
+
varcontainer=newContainer();
754
+
755
+
container.Register<A>(Reuse.Singleton);
756
+
container.Register<B>(Reuse.Singleton);
757
+
758
+
// injecting A and B for X created via delegate
759
+
container.RegisterDelegate<A, B, X>((a, b) =>newX(a, b));
760
+
761
+
Assert.IsNotNull(container.Resolve<X>());
762
+
}
763
+
764
+
classA {}
765
+
classB {}
766
+
classX
767
+
{
768
+
publicX(Aa, Bb) {}
769
+
}
770
+
}
771
+
772
+
```
773
+
774
+
### RegisterDelegate is harder to use when types are not known
731
775
732
776
Another thing, that delegate is usually hard to use when types are not known in the compile time.
733
777
Given `type = typeof(Foo)` it is impossible to write `new type();`.
@@ -750,26 +794,6 @@ class Register_delegate_returning_object
750
794
}
751
795
```
752
796
753
-
754
-
### Will not detect recursive dependencies
755
-
756
-
When using normal typed registration DryIoc will detect [recursive dependencies](ErrorDetectionAndResolution#RecursiveDependencyDetected).
757
-
758
-
But when using the delegate registration DryIoc is unable to analyze what dependencies are used inside delegate.
759
-
That is another reason to avoid `RegisterDelegate` whatsoever:
0 commit comments