Software Design Blog - Dependency Injection Simple solutions to solve complex problems / http://www.rssboard.org/rss-specification BlogEngine.NET 3.1.1.0 en-US /opml.axd http://www.dotnetblogengine.net/syndication.axd Jay Strydom Software Design Blog 0.000000 0.000000 Late binding principle: defer resource binding to improve flow <img class="img-responsive" src="/pics/banners/IncreaseFlowBlog.jpg"> <br> <p>Donald G. Reinertsen, author of �The Principles of Product Development Flow�, asked the question should we assign a resource to a task at the start of a project?</p> <p>Let�s explore this questions in our software examples below. Will delaying assignment produce light classes, with less memory consumption, and reduced computing waste?</p> <p><b>The problem</b> is how can you delay resource demands during object construction? For example, using dependency injection (DI), how do you inject dependencies into a class and delay the construction of these dependencies at the same time?</p> <p><b>The solution</b> is to use automatic factories to delay resource demands until it is used.</p> <a class="btn btn-primary btn-sm" role="button" href="/Downloads/UnityFactories.zip">Download Source Code</a> <h3>Setting the scene</h3> <p>This post will use an illustration of a cloud storage service that relies on an expensive online connection resource. Let�s assume that we cannot modify the constructor behaviour of the resource class. The interfaces and resource implementation are shown below.</p> <pre class="brush: c-sharp;"> public interface IStorageService { void Save(string path, Stream stream); bool HasSufficientSpace(int requiredSizeMb); } public interface IStorageResource { void UploadStream(string path, Stream stream); } public class CloudStorage : IStorageResource { public CloudStorage() { Console.WriteLine("Establishing cloud connection..."); // Simulate expensive initialisation System.Threading.Thread.Sleep(5000); } public void UploadStream(string path, Stream stream) { // your code here } } public class CloudStorageService : IStorageService { private readonly IStorageResource _resource; public CloudStorageService(IStorageResource resource) { if (resource == null) throw new ArgumentNullException("resource"); _resource = resource; } public void Save(string path, Stream stream) { Console.WriteLine("Called Save"); _resource.UploadStream(path, stream); } public bool HasSufficientSpace(int requiredSizeMb) { Console.WriteLine("Called HasSufficientSpace"); return true; // No need to check, the cloud service has unlimited space } } </pre> <h3>Evaluating the results</h3> <p>Let�s run the code and observe the output.</p> <pre class="brush: c-sharp;"> var container = new UnityContainer(); container.RegisterType&lt;IStorageService, CloudStorageService&gt;(); container.RegisterType&lt;IStorageResource, CloudStorage&gt;(); var storageService = container.Resolve&lt;IStorageService&gt;(); if (storageService.HasSufficientSpace(100)) { using (var fileStream = System.IO.File.OpenRead(@"C:\Temp\File.txt")) { storageService.Save(@"Files\File01.txt", fileStream); } } </pre> <pre>Establishing cloud connection... Called HasSufficientSpace Called Save </pre> <div class="alert alert-warning" role="alert"> <b>Oops!</b> The resource was initialised before it was used. </div> <p>The CloudStorageService class is poorly implemented because:</p> <ul> <li>The resource dependency is demanded in the constructor causing a significant start-up delay. By default, Windows will refuse to start the service if it takes longer than 30 sec to initialise.</li> <li>System memory and computing cycles are wasted since the resource may never be used.</li> </ul> <h3>Late binding with an Auto Factory</h3> <p>We are only going to change the CloudStorageService class. Everything else will remain the same, which minimises the risk of potential regression.</p> <p>The auto factory version is shown below.</p> <pre class="brush: c-sharp;"> public class CloudStorageServiceAutoFactory : IStorageService { private readonly Lazy&lt;IStorageResource&gt; _resource; public CloudStorageServiceAutoFactory(Func&lt;IStorageResource&gt; resource) { if (resource == null) throw new ArgumentNullException("resource"); _resource = new Lazy&lt;IStorageResource&gt;(resource); } private IStorageResource Resource { get { return _resource.Value; } } public void Save(string path, Stream stream) { Console.WriteLine("Called Save"); Resource.UploadStream(path, stream); } public bool HasSufficientSpace(int requiredSizeMb) { Console.WriteLine("Called HasSufficientSpace"); return true; // Cloud service has unlimited space } } </pre> <div class="alert alert-info" role="alert"> <b>Note:</b> Unity will automatically pass in a func&lt;IStorageResource&gt; lamba factory function so your bootstrap code doesn�t have to change. </div> <p>Let�s call the improved CloudStorageServiceAutoFactory class instead.</p> <pre>Called HasSufficientSpace Called Save Establishing cloud connection... </pre> <div class="alert alert-success" role="alert"> <b>Success!</b> The resource demands were deferred until the resource was needed. </div> <h3>Why is this a great solution?</h3> <p>Here is an alternative version as covered in a <a href="http://www.devtrends.co.uk/blog/using-unitys-automatic-factories-to-lazy-load-expensive-dependencies" target="_blank">DevTrends</a> post:</p> <pre class="brush: c-sharp;"> public class CloudStorageServiceBad : IStorageService { private readonly Func&lt;IStorageResource&gt; _factory; private IStorageResource _resource; public CloudStorageServiceBad(Func&lt;IStorageResource&gt; factory) { if (factory == null) throw new ArgumentNullException("factory"); _factory = factory; } private IStorageResource Resource { get { return _resource ?? (_resource = _factory()); } } // The methods goes here } </pre> <div class="alert alert-warning" role="alert"> <b>Warning!</b> Bad code, do not copy. </div> <p>The code above is bad because:</p> <ul> <li>A reference is required to the factory and resource, yet the factory is only used once</li> <li>Performing lazy loading in the Resource property is not thread safe</li> </ul> <p>The solution as shown in the CloudStorageServiceAutoFactory class will pass the factory to Lazy&lt;IStorageResource&gt;, which requires less code and is thread safe. See <a href="/post/evolution-of-the-singleton-design-pattern">this post</a> about thread safety.</p> <p>Let�s compare the output of the two solutions by executing the method in multiple threads:</p> <pre class="brush: c-sharp;"> Parallel.Invoke(() =&gt; storageService.Save(@"Files\File01.txt", null), () =&gt; storageService.Save(@"Files\File01.txt", null)); </pre> <p>CloudStorageServiceBad output:</p> <pre>Called Save Called Save Establishing cloud connection... Establishing cloud connection... </pre> <p>CloudStorageServiceAutoFactory output:</p> <pre>Called Save Called Save Establishing cloud connection... </pre> <div class="alert alert-success" role="alert"> <b>Success!</b> The CloudStorageServiceAutoFactory class is thread safe. </div> <h3>Manual Construction</h3> <p>For those out there who haven�t transitioned to DI yet, but I <a href="/post/step-by-step-guide-to-use-dependency-injection">highly recommend</a> that you do, here is how you would wire it up manually:</p> <pre class="brush: c-sharp;"> var service = new CloudStorageServiceAutoFactory(() =&gt; new CloudStorage()); </pre> <h3>Summary</h3> <p>This post illustrated how to improve memory utilisation and to reduce computing waste using automatic factories to delay expensive resource demands.</p> <p>Delaying the demand of resources until the code paths are actually executed can significantly improve application performance.</p> /post/Late-binding-principle-defer-resource-binding-to-improve-flow [email protected] /post/Late-binding-principle-defer-resource-binding-to-improve-flow#comment /post.aspx?id=50ecf780-9515-46d9-aa67-4b5b75394305 Fri, 29 Jan 2016 10:39:00 +1300 Dependency Injection Software Design C# .NET Jay Strydom /pingback.axd /post.aspx?id=50ecf780-9515-46d9-aa67-4b5b75394305 0 /trackback.axd?id=50ecf780-9515-46d9-aa67-4b5b75394305 /post/Late-binding-principle-defer-resource-binding-to-improve-flow#comment /syndication.axd?post=50ecf780-9515-46d9-aa67-4b5b75394305 A step-by-step guide to detect errors and retry operations <img class="img-responsive" src="/pics/banners/ImproveReliabilityBlog.jpg"> <br> <p> We are liable for the reliability of our apps, which work when tested but fail in production environments due to unexpected temporary conditions. Errors can occur due to an intermittent service, infrastructure fault, network issue or explicit throttling. If the operation is retried a short time later (maybe a few milliseconds later) the operation may succeed. </p> <p>A lazy brain can quickly solve this problem without a lot of planning, flexibility or configuration in mind as shown in this <a href="https://msdn.microsoft.com/en-us/library/system.net.mail.smtpexception(v=vs.110).aspx#Anchor_8" target="_blank">MSDN sample</a> that performs a retry when the SMTP mail client fails.</p> <pre class="brush: c-sharp;"> try { client.Send(message); } catch (SmtpFailedRecipientsException ex) { for (int i = 0; i &lt; ex.InnerExceptions.Length; i++) { SmtpStatusCode status = ex.InnerExceptions[i].StatusCode; if (status == SmtpStatusCode.MailboxBusy || status == SmtpStatusCode.MailboxUnavailable) { System.Threading.Thread.Sleep(5000); client.Send(message); } } } </pre> <div class="alert alert-warning" role="alert"> <b>Warning!</b> Bad code, do not copy. </div> <p><b>The problem</b> is how do you retry a failed operation correctly?</p> <p><b>The solution</b> is to create an error detection strategy to determine if the error can be retried and use a retry policy to define the number of retries and frequency between retries.</p> <p>This post extends the <a href="/post/step-by-step-guide-to-use-dependency-injection">previous example</a> by adding retry logic to the SMTP Mail Client. The aim is to illustrate how to improve the reliability of an app by making it more robust.</p> <div class="alert alert-info" role="alert"> <b>Note:</b> The approach used in this post is generic and can be applied to database repositories, cloud services, web services and more. </div> <a class="btn btn-primary btn-sm" role="button" href="/Downloads/OrderApplicationRetry.zip">Download Source Code</a> <h3>Retry Solution - Done Properly</h3> <p>Let�s get started by implementing clean retry code in 4 easy steps.</p> <h5>Step 1 � Add the transient fault handling NuGet package</h5> <p>The Microsoft transient fault handling NuGet package contains generic, reusable and testable components that we will use for solving the SMTP mail client retry problem.</p> <p>Add the <a href="https://www.nuget.org/packages/EnterpriseLibrary.TransientFaultHandling/" target="_blank">EnterpriseLibrary.TransientFaultHandling</a> NuGet package to the Orders.Implementation project.</p> <h5>Step 2 � Create a transient error detection strategy</h5> <p>Transient (temporarily) faults are errors that can be retried. Here are a few examples of transient errors that may work if retried:</p> <ul> <li>The host is not responding or is unavailable</li> <li>The server is busy or the connection was dropped</li> </ul> <p>Here are a few examples of permanent errors that won�t work even if retried:</p> <ul> <li>Authentication failed (invalid username or password)</li> <li>Bad request (invalid email address, attachment not found)</li> </ul> <p>Let�s create a detection strategy that will detect SMTP Mail errors that can be retried.</p> <pre class="brush: c-sharp;"> public class SmtpMailErrorDetectionStrategy : ITransientErrorDetectionStrategy { public bool IsTransient(Exception ex) { var smtpFailedException = ex as SmtpFailedRecipientsException; if (smtpFailedException == null) return false; return smtpFailedException.InnerExceptions .Any(mailEx =&gt; mailEx.StatusCode == SmtpStatusCode.MailboxBusy || mailEx.StatusCode == SmtpStatusCode.MailboxUnavailable); } } </pre> <h5>Step 3 � Create the SMTP Retry Decorator</h5> <p>Based on to the single responsibility principle (SRP), the mail client should only be responsible for one thing, which is sending mail. Adding error detection and retry logic violates the SRP since it shouldn't be it's problem.</p> <p>The decorator pattern is great for extending an existing class. Just imagine how large the class will become if we continually add cross-cutting functionality to it such as retries, logging and performance monitoring.</p> <p>Here is the existing SMTP mail client used in the <a href="/post/step-by-step-guide-to-use-dependency-injection">previous post</a>:</p> <img class="img-responsive" src="/pics/blogs/EmailServiceFailure.png"> <br> <p>We are going to decorate the SMTP mail client with a retry mail client decorator as shown below:</p> <img class="img-responsive" src="/pics/blogs/EmailServiceFailureRetry.png"> <pre class="brush: c-sharp;"> public class SmtpMailClientRetryDecorator : IMailClient { private readonly IMailClient _next; private readonly RetryPolicy _retryPolicy; public SmtpMailClientRetryDecorator(IMailClient next, RetryPolicy retryPolicy) { if (next == null) throw new ArgumentNullException("next"); if (retryPolicy == null) throw new ArgumentNullException("retryPolicy"); _next = next; _retryPolicy = retryPolicy; } public void Send(string to, string subject, string body) { _retryPolicy.ExecuteAction(() =&gt; _next.Send(to, subject, body)); } } </pre> <h5>Step 4 � Compose the Solution</h5> <p>The transient fault handling library provides the following retry strategies:</p> <table class="table table-bordered"> <tbody><tr><th> <p>Retry strategy</p> </th><th> <p>Example (intervals between retries in seconds)</p> </th></tr> <tr><td data-th=" Retry strategy "> <p>Fixed interval</p> </td><td data-th=" Example (intervals between retries in seconds) "> <p>2,2,2,2,2,2</p> </td></tr> <tr><td data-th=" Retry strategy "> <p>Incremental intervals</p> </td><td data-th=" Example (intervals between retries in seconds) "> <p>2,4,6,8,10,12</p> </td></tr> <tr><td data-th=" Retry strategy "> <p>Random exponential back-off intervals</p> </td><td data-th=" Example (intervals between retries in seconds) "> <p>2, 3.755, 9.176, 14.306, 31.895</p> </td></tr> </tbody></table> <p>Let�s register the fixed interval retry strategy in the Unity IoC container as shown below. If you are new to Dependency Injection (DI), <a href="/post/step-by-step-guide-to-use-dependency-injection">read this post</a>.</p> <pre class="brush: c-sharp;"> // This should be defined in app settings const int maxRetries = 5; var retryInterval = TimeSpan.FromSeconds(2); _container.RegisterType&lt;FixedInterval&gt;( new InjectionConstructor(maxRetries, retryInterval)); _container.RegisterType&lt;RetryPolicy&lt;SmtpMailErrorDetectionStrategy&gt;&gt;( new InjectionConstructor(new ResolvedParameter&lt;FixedInterval&gt;())); _container.RegisterType&lt;IMailClient, SmtpMailClient&gt;(typeof(SmtpMailClient).FullName); _container.RegisterType&lt;IMailClient, SmtpMailClientRetryDecorator&gt;( new InjectionConstructor( new ResolvedParameter&lt;IMailClient&gt;(typeof(SmtpMailClient).FullName), </pre> <div class="alert alert-success" role="alert"> <b>Success!</b> We have added a flexible retry solution to our app. </div> <p>And for those who may think this is over-engineered and too complicated then this is how you can construct the retry policy in the SMTP mailer class � but of course you will run in to the problems discussed in earlier posts!</p> <pre class="brush: c-sharp;"> const int maxRetries = 5; var retryInterval = TimeSpan.FromSeconds(2); var policy = new RetryPolicy&lt;SmtpMailErrorDetectionStrategy&gt;( new FixedInterval(maxRetries, retryInterval)); policy.ExecuteAction(() =&gt; client.Send(mesage)); </pre> <h3>Summary</h3> <p>This post showed how to implement a flexible, configurable solution using the <a href="https://msdn.microsoft.com/en-us/library/dn440719(v=pandp.60).aspx" target="_blank">Microsoft Transient Fault Handling Application Block</a> to retry transient failures in order to improve app reliability.</p> <p>If we refer to the original <a href="https://msdn.microsoft.com/en-us/library/system.net.mail.smtpexception(v=vs.110).aspx#Anchor_8" target="_blank">MSDN code sample</a>, we can see a similar pattern by evaluating specific transient error codes (<i>transient error detection strategy</i>), pausing for 5 seconds (<i>retry policy - retry Interval</i>) and retrying the send operation once (<i>retry policy - retry count</i>).</p> /post/a-step-by-step-guide-to-detect-errors-and-retry-operations [email protected] /post/a-step-by-step-guide-to-detect-errors-and-retry-operations#comment /post.aspx?id=6459fc61-6209-44fb-aa9e-773cfc1cba21 Tue, 26 Jan 2016 21:35:00 +1300 Dependency Injection Design Patterns Decorator Pattern .NET C# Jay Strydom /pingback.axd /post.aspx?id=6459fc61-6209-44fb-aa9e-773cfc1cba21 0 /trackback.axd?id=6459fc61-6209-44fb-aa9e-773cfc1cba21 /post/a-step-by-step-guide-to-detect-errors-and-retry-operations#comment /syndication.axd?post=6459fc61-6209-44fb-aa9e-773cfc1cba21 How to structure DI registration code cleanly <img class="img-responsive" src="/pics/banners/DIRegistrationCleanupBlog.jpg"> <br> <p>The <a href="/post/step-by-step-guide-to-use-dependency-injection">previous post</a> introduced dependency injection (DI). This post will provide a practical approach to wire up DI cleanly.</p> <p><b>The problem</b> is where do we keep our dependency injection registration bootstrap/wiring code?</p> <ul> <li>We don�t want a giant central registration assembly or a monolithic global.asax class</li> <li>We don�t want to bleed DI into our implementation assemblies that requires DI references</li> <li>We don�t want to be locked into a specific DI framework</li> </ul> <p><b>The solution</b> is to componentise registrations and keep DI frameworks out of our implementation and interface libraries.</p> <a class="btn btn-primary btn-sm" role="button" href="/Downloads/OrderApplicationUnityMef.zip">Download Source Code</a> <h3>What is Unity?</h3> <p>Unity is a DI container which facilitates building loosely coupled apps. It provides features such as object lifecycle management, registration by convention and instance/type interception.</p> <h3>What is MEF?</h3> <p>The Managed Extensibility Framework (MEF) provides DI container capabilities to build loosely coupled apps. It allows an app to discover dependencies implicitly with no configuration required by declaratively specifying the dependencies (known as <i>imports</i>) and what capabilities (known as <i>exports</i>) that are available.</p> <h3>MEF vs Unity</h3> <p>MEF and Unity provide similar capabilities but they both have strengths and weaknesses.</p> <ul> <li>Unity has greater DI capabilities � such as interception</li> <li>Unity is less invasive since MEF requires developers to sprinkle [Import] and [Export] attributes all throughout the code</li> <li>MEF has great discoverability features that are not available in Unity</li> </ul> <div class="alert alert-success" role="alert"> <b>The Winner:</b> MEF for discovery + Unity for DI </div> <h3>Setup</h3> <p>The solution layout of the <a href="/post/step-by-step-guide-to-use-dependency-injection">previous DI introduction post</a> is shown below.</p> <img class="img-responsive" src="/pics/blogs/DIProjectLayoutBefore.png"> <br> <p>All of the bootstrapping code currently lives in the OrderApplication console assembly. The registration can quickly get out of hand with a large app with many components. The registration is also not discoverable which means we can�t just drop in new dlls to automatically replace existing functionality or add new functionality.</p> <h3>Clean Wiring</h3> <p>Let�s get started with clean wiring in 3 steps.</p> <h5>1. Move each components� DI registration to its own assembly</h5> <pre class="brush: c-sharp;"> // Orders.Bootstrap.dll public class Component { private readonly IUnityContainer _container; public Component(IUnityContainer container) { if (container == null) throw new ArgumentNullException("container"); _container = container;; } public void Register() { _container.RegisterType&lt;IOrderRepository, OrderRepository&gt;(); _container.RegisterType&lt;IEmailService, EmailService&gt;(); _container.RegisterType&lt;IRenderingService, RazaorRenderingService&gt;(); _container.RegisterType&lt;IMailClient, SmtpMailClient&gt;(); _container.RegisterType&lt;IOrderService, OrderService&gt;(); var baseTemplatePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EmailTemplates"); _container.RegisterType&lt;ITemplateLocator, TemplateLocator&gt;( new InjectionConstructor(baseTemplatePath)); } } </pre> <div class="alert alert-success" role="alert"> <b>Solved!</b> The Orders.Implementation and Orders.Interfaces assemblies are no longer coupled to a specific DI framework since it doesn�t know about DI. </div> <h5>2. Discover and bootstrap your registration</h5> <p>MEF is great at discovering assemblies so let�s create an interface that can be discovered by exporting the bootstrap interface.</p> <pre class="brush: c-sharp;"> // Bootstrap.Interfaces.dll public interface IBootstrap { void Register(); } </pre> <p>Add the MEF export attribute to the bootstrap component created in step 1. </p><pre class="brush: c-sharp;"> [Export(typeof(IBootstrap))] public class Component : IBootstrap { private readonly IUnityContainer _container; [ImportingConstructor] public Component(IUnityContainer container) { if (container == null) throw new ArgumentNullException("container"); _container = container;; } public void Register() { // Registration code from step 1 } } </pre> <p>The ResolvingFactory below will perform the discovery and Unity registration.</p> <pre class="brush: c-sharp;"> // Bootstrap.Implementation.dll public class ResolvingFactory { [ImportMany(typeof(IBootstrap))] private IEnumerable&lt;IBootstrap&gt; Bootstraps { get; set; } private readonly IUnityContainer _container; public ResolvingFactory() { _container = new UnityContainer(); Initialise(); } private void Initialise() { var catalog = new AggregateCatalog(); catalog.Catalogs.Add(new DirectoryCatalog(GetBinPath())); using (var mefContainer = new CompositionContainer(catalog)) { mefContainer.ComposeExportedValue(_container); mefContainer.SatisfyImportsOnce(this); } foreach (var bootstrap in Bootstraps) { bootstrap.Register(); } } public string GetBinPath() { var domainSetup = AppDomain.CurrentDomain.SetupInformation; return !string.IsNullOrEmpty(domainSetup.PrivateBinPath) ? domainSetup.PrivateBinPath : domainSetup.ApplicationBase; } public T Resolve&lt;T&gt;() { return _container.Resolve&lt;T&gt;(); } } </pre> <p>The new project assembly layout is shown below.</p> <img class="img-responsive" src="/pics/blogs/DIProjectLayoutAfter.png"> <h5>3. Run the solution</h5> <p>Let�s run the new Unity + MEF solution.</p> <pre class="brush: c-sharp;"> // OrderApplication.dll static void Main(string[] args) { var orderModel = new OrderModel() { Description = "Design Book", Customer = new CustomerModel() { Email = "[email protected]", Name = "Jay" } }; var factory = new ResolvingFactory(); var orderService = factory.Resolve&lt;IOrderService&gt;(); orderService.Create(orderModel); } </pre> <div class="alert alert-success" role="alert"> <b>Solved!</b> Simply drop a new bootstrap dll in the app directory and it will be registered automatically. </div> <h3>Summary</h3> <p>DI code often becomes messy with large amounts of registrations.</p> <p>This post shows how DI registration can be componentised to keep code clean, simple and discoverable.</p> /post/how-to-structure-di-registration-code-cleanly [email protected] /post/how-to-structure-di-registration-code-cleanly#comment /post.aspx?id=c68f54a4-9d92-4534-8422-c5c64c2b6da8 Thu, 21 Jan 2016 06:43:00 +1300 Dependency Injection Software Design .NET C# Jay Strydom /pingback.axd /post.aspx?id=c68f54a4-9d92-4534-8422-c5c64c2b6da8 0 /trackback.axd?id=c68f54a4-9d92-4534-8422-c5c64c2b6da8 /post/how-to-structure-di-registration-code-cleanly#comment /syndication.axd?post=c68f54a4-9d92-4534-8422-c5c64c2b6da8