Dependency injection with unity 2.0 Dmytro Mindra Lohika

0 views

Published on

Dependency injection with unity 2.0 Dmytro Mindra Lohika

1 Comment
5 Likes
Statistics
Notes
No Downloads
Views
Total views
0
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
72
Comments
1
Likes
5
Embeds 0
No embeds

No notes for slide

Dependency injection with unity 2.0 Dmytro Mindra Lohika

  1. 1. Dependency Injection with Unity 2.0<br />DmytroMindra<br />RnD Tech Lead<br />Lohika<br />Вторая встреча Microsoft .Net User Group Одесса, 2010<br />
  2. 2. Goal<br />Get DI understanding<br />Get Unity 2.0 understanding<br />Learn how to add Unity 2.0 to your projects<br />
  3. 3. Plan<br />Inversion of Control principle (IoC)<br />Dependency Injection pattern (DI)<br />Unity 2.0<br />Live Demo<br />
  4. 4. Problem<br />
  5. 5. Problem<br />We live in an age where writing software to a given set of requirements is no longer enough.<br />We have to maintain and change existing code.<br />
  6. 6. How?<br />Our solutions should be:<br />Modular<br />Testable<br />Adaptive to change<br />
  7. 7. Terms<br />Service —An object that performs a well-defined function when called upon<br />Client—Any consumer of a service; an object that calls upon a service to perform a well-understood function<br />
  8. 8. Terms<br />Dependency —A specific service that is required by another object to fulfill its function.<br />Dependent—A client object that needs a dependency (or dependencies) in order to perform its function.<br />
  9. 9. PRE DI APPROACHES<br />
  10. 10. Ex1:Composition<br />
  11. 11. Ex1:Composition<br />public class SpellCheckerService{}<br />public class TextEditor<br /> {<br />private SpellCheckerService _spellCheckerService;<br />public TextEditor()<br /> {<br /> _spellCheckerService = new SpellCheckerService(); <br /> }<br /> }<br />class Program<br /> {<br />static void Main(string[] args)<br /> {<br />TextEditor textEditor = new TextEditor();<br /> }<br /> }<br />
  12. 12. What’s good<br />It’s simple<br />
  13. 13. What’s bad<br />It’s not testable<br />It’s hard to maintain/change<br />
  14. 14. Ex2: Factory<br />
  15. 15. Ex2: Factory<br /> public interface ISpellCheckerService<br /> {<br />string CheckSpelling();<br /> }<br />
  16. 16. Ex2: Factory<br /> public class SpellCheckerService: ISpellCheckerService<br /> {<br />public string CheckSpelling()<br /> {<br /> return “Real”;<br /> }<br /> }<br />
  17. 17. Ex2: Factory<br />public class SpellCheckerFactory<br /> {<br />private static ISpellCheckerService _spellCheckerService = new SpellCheckerService();<br /> public static ISpellCheckerServiceSpellCheckerService<br /> {<br />get{ return _spellCheckerService; }<br /> set{ _spellCheckerService = value; }<br /> }<br /> }<br />
  18. 18. Ex2: Factory<br />public class TextEditor<br />{<br />private ISpellCheckerService _spellCheckerService;<br />public TextEditor()<br /> {<br /> _spellCheckerService = SpellCheckerFactory.SpellCheckerService;<br /> }<br />public string CheckSpelling()<br /> {<br /> return _spellCheckerService.CheckSpelling();<br /> }<br />}<br />
  19. 19. Ex2:Factory Unit Testing<br /> public class SpellCheckerServiceMock: ISpellCheckerService<br /> {<br />public string CheckSpelling()<br /> {<br /> return “Mock”;<br /> }<br />}<br />
  20. 20. Ex2:Factory Unit Testing<br />[TestFixture]<br />class EmailerFactoryUnitTests<br /> {<br /> [Test]<br />public void EmailerFactoryTest()<br /> {<br />ISpellCheckerServicemockSpellCheckerService = new SpellCheckerServiceMock();<br />SpellCheckerFactory.SpellCheckerService = mockSpellCheckerService;<br />TextEditortextEditor = new TextEditor();<br />Assert.AreEqual(“Mock”, textEditor.CheckSpelling());<br /> }<br /> }<br />
  21. 21. Ex2: Factory<br />
  22. 22. What changed<br />TextEditor is still looking for its dependencies by itself. But now we can plug in different services without letting him know.<br />
  23. 23. What’s good<br />It’s testable<br />It’s easier to maintain/change<br />
  24. 24. What’s bad<br />You have to maintain factory or service locator<br />Dependent is still looking for Dependencies by himself.<br />Dependencies are encapsulated and are not obvious.<br />
  25. 25. Service Locator<br />Unfortunately, being a kind of Factory, Service Locators suffer from the same problems<br />of testability and shared state.<br />
  26. 26. Inversion of Control<br />Common Flow<br />TextEditor creates its dependency by himself.<br />IoC Flow<br />TextEditor requests factory to create dependency for him.<br />
  27. 27. Inversion of Control<br />Hollywood Principle: <br />Don’t call me, I’ll call you<br />
  28. 28. Inversion of Control<br />IoC –  is a common characteristic of frameworks.<br />Inversion of Control serves as a design guideline.<br />According to Martin Fowler the etymology of the phrase dates back to 1988.<br />
  29. 29. Two principles of IOC<br />Main classes aggregating other classes should not depend on the direct implementation of the aggregated classes. Both the classes should depend on abstraction. <br />Abstraction should not depend on details, details should depend on abstraction.<br />
  30. 30. Inversion of Controlas a Design Guideline<br />Without IoC<br />With IoC<br />Loose coupling<br />
  31. 31. Time TO INJECT !<br />
  32. 32. Ex3:Dependency Injection<br />public class TextEditor<br /> {<br />private readonlyISpellCheckerService _spellCheckerService;<br />public TextEditor(ISpellCheckerServicespellCheckerService)<br /> {<br /> _spellCheckerService = spellCheckerService;<br /> }<br />public string CheckSpelling()<br /> {<br /> return _spellCheckerService.CheckSpelling();<br /> }<br />}<br />
  33. 33. Ex3: Unit Testing DI<br />Almost same as for Ex2<br />// Mock <br />ISpellCheckerService mock = new SpellCheckerServiceMock();<br />// Instantiate<br />TextEditortextEditor = new TextEditor(mock);<br />// Check<br />Assert.AreEqual(“Mock”, textEditor.CheckSpelling());<br />
  34. 34. What changed<br />TextEditor lost its “Sovereignty” and is not able to resolve dependencies by himself.<br />
  35. 35. What’s good<br />Dependencies are obvious.<br />Dependency resolution is not encapsulated.<br />Unit Testing got little bit easier<br />Architecture is much better<br />
  36. 36. What’s bad<br />We are resolving dependencies manually while creating instances of TextEditor.<br />
  37. 37. Dependency Injection<br />
  38. 38. Dependency Injection<br />DI is IoC<br />Inversion of Control is too generic a term<br />DI pattern – describes the approach used to lookup a dependency. <br />Dependency resolution is moved to Framework.<br />
  39. 39. Ex4: Unity<br />
  40. 40. Ex4: Unity<br />using Microsoft.Practices.Unity;<br />UnityContainer container = new UnityContainer();<br />container.RegisterType<ISpellCheckerService, SpellCheckingService>();<br />TextEditortextEditor = container.Resolve<TextEditor>();<br />
  41. 41. What changed<br />Unity container now resolves dependencies<br />
  42. 42. What’s good<br />Automated dependency resolution<br />
  43. 43. Unity methods<br />RegisterType<br />RegisterInstance<br />Resolve<br />BuildUp<br />
  44. 44. Ex5: Unity Configuration<br />   <configSections>   <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>  </configSections>  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">    <alias alias="ISpellCheckerService" type="Unity.Config.ISpellCheckerService, Unity.Config" />    <alias alias="SpellCheckingService" type="Unity.Config.SpellCheckingService, Unity.Config" />    <namespace name="Unity.Config" />    <assembly name="Unity.Config" />    <container>      <register type="ISpellCheckerService" mapTo="SpellCheckingService" />    </container>  </unity><br />
  45. 45. Ex5: Unity Configuration<br /> using Microsoft.Practices.Unity;using Microsoft.Practices.Unity.Configuration;UnityContainer container = new UnityContainer();container.LoadConfiguration();TextEditor textEditor = container.Resolve<TextEditor>();<br />
  46. 46. Dependency tree<br />
  47. 47. Ex6: Dependency tree<br />public interface IAdditionalDependency{}<br />public class AdditionalDependency : IAdditionalDependency{}<br />public class SpellCheckingService: ISpellCheckerService<br /> {        public SpellCheckingService( IAdditionalDependency dependency){}<br />  }<br />
  48. 48. Ex6: Dependency Tree<br />UnityContainer container = new UnityContainer();container.RegisterType<ISpellCheckerService, SpellCheckingService>();container.RegisterType<IAdditionalDependency, <br />AdditionalDependency>();TextEditor textEditor = container.Resolve<TextEditor>();<br />
  49. 49. Ex6: Dependency tree<br />
  50. 50. Injection Types<br />Constructor Injection<br />Setter injection<br />Method call injection<br />
  51. 51. Ex7: Defining Injection Constructor<br />    public class TextEditor    {        private readonly ISpellCheckerService _spellCheckerService;        [InjectionConstructor]                public TextEditor(ISpellCheckerService spellCheckerService)        {            _spellCheckerService = spellCheckerService;        }        public TextEditor(ISpellCheckerService spellCheckerService,string name)        {            _spellCheckerService = spellCheckerService;        }    }<br />
  52. 52. Ex8: Property Injection<br />    public class TextEditor    {        public ISpellCheckerService SpellCheckerService {get; set;}        [Dependency]        public ISpellCheckerService YetAnotherSpellcheckerService{get;set;}    }<br />            UnityContainer container = new UnityContainer();            container.RegisterType<TextEditor>(new InjectionProperty("SpellCheckerService"));            container.RegisterType<ISpellCheckerService, SpellCheckingService>();            TextEditor textEditor = container.Resolve<TextEditor>();<br />
  53. 53. Ex9: Method call injection<br />    public class TextEditor    {        public ISpellCheckerService SpellcheckerService {get; set;}<br />        [InjectionMethod]        public void Initialize (ISpellCheckerService spellcheckerService)        {            _spellCheckerService = spellcheckerService;        }    <br />}<br />UnityContainer container = new UnityContainer();//container.RegisterType<TextEditor>(<br />new InjectionMethod("SpellcheckerService"));container.RegisterType<ISpellCheckerService, SpellCheckingService>();TextEditor textEditor = container.Resolve<TextEditor>();<br />
  54. 54. Lifetime Managers<br />TransientLifetimeManagerReturns a new instance of the requested type for each call. (default behavior)<br />ContainerControlledLifetimeManagerImplements a singleton behavior for objects. The object is disposed of when you dispose of the container. <br />
  55. 55. Lifetime Managers<br />ExternallyControlledLifetimeManagerImplements a singleton behavior but the container doesn't hold a reference to object which will be disposed of when out of scope. <br />HierarchicalifetimeManagerImplements a singleton behavior for objects. However, child containers don't share instances with parents.<br />
  56. 56. Lifetime Managers<br />PerResolveLifetimeManagerImplements a behavior similar to the transient lifetime manager except that instances are reused across build-ups of the object graph. <br />PerThreadLifetimeManagerImplements a singleton behavior for objects but limited to the current thread.<br />
  57. 57. Ex10: Unity Singleton<br />UnityContainer container = new UnityContainer();container.RegisterType<ISpellCheckerService, SpellCheckingService>(new ContainerControlledLifetimeManager());TextEditor textEditor = container.Resolve<TextEditor>();<br />
  58. 58. Container Hierarchy<br />
  59. 59. Unity Limitations<br /><ul><li>When your objects and classes have no dependencies on other objects or classes.
  60. 60. When your dependencies are very simple and do not require abstraction. </li></li></ul><li>What Unity stands for<br />For<br />Wiring framework components<br />Not for<br />Wiring small parts<br />
  61. 61. Performance<br />
  62. 62. Performance<br />
  63. 63. Performance<br />
  64. 64. .NET DI Frameworks<br />Unity 2.0<br />AutoFac 2.3.2<br />StructureMap 2.6.1<br />Castle Windsor 2.1<br />Ninject 2.0<br />
  65. 65. Additional reading<br />
  66. 66. Additional reading<br />
  67. 67. Live Demo<br />
  68. 68. Questions ?<br />
  69. 69. Thank YOU !<br />

×