Thank you for your feedback Jonnie, and thank you for reading our book.

The cooking analogies are inherited from the first edition. When starting planning the second edition of this book, Mark and I choose to keep the analogies in place, as we felt it was more valuable to spend our time on other parts of the book. Besides, your comment is actually the first complaint we received about the cooking analogies in the last two years.

Apart from that, we're currently one or two weeks before going to print. There is no way we could rewrite all chapter introductions. And even if we were able to do so, Manning would absolutely not allow us to do so.

So I'm afraid you'll have to live with that. Hopefully the rest of the book still gives you a lot of new knowledge. And on the plus side, the analogy is typically just spans half a page. You can easily scan through it if you don't like it.

Steven
Your current implementation is certainly not the best implementation. You should never start a scope in the constructor. The constructor should do nothing but storing incoming dependencies (as we explain in chapter 4).

Besides, starting the scope at that point is too late, as the decorated handler has already been created. Instead, you should do the following:

public class ThreadScopedQueryHandlerDecorator<TQuery, TResult> : IQueryHandler<TQuery, TResult>
    where TQuery : IQuery<TResult>
{
    private readonly Func<IQueryHandler<TQuery, TResult>> decoratedFactory;
    private readonly Container container;

    public ThreadScopedQueryHandlerDecorator(
        Func<IQueryHandler<TQuery, TResult>> decoratedFactory,
        Container container) {
        this.decorated = decorated;
        this.container = container;
    }

    public TResult Handle(TQuery query) {
        using (ThreadScopedLifestyle.BeginScope(this.container)) {
            var decorated = this.decoratedFactory();
            return this.decorated.Handle(query);
        }
    }
}


This does a few things:

* Instead of injecting the decorated handler, you inject a factory that will be able to create the decorated handler
* When Handle is called a new Scope is started
* Within that scope, the factory is invoked and the handler will be created.
* When the method returns, the scope is disposed, and with it, all scoped dependencies created during that scope.

Because both the Container and the factory are singletons, you can register this decorator as singleton as well, even though its decoratees aren't:

container.RegisterDecorator(
    typeof(IQueryHandler<,>),
    typeof(ThreadScopedQueryHandlerDecorator<,>),
    Lifestyle.Singleton);


You'll actually find an example of a very similar decorator in the Simple Injector documentation: https://simpleinjector.org/aop#decorators-with-func-t-decoratee-factories
Consider the following small program:

using System;
using SimpleInjector;

// Abstractions
public interface IQuery<TResult> { }
public interface IQueryHandler<TQuery, TResult> where TQuery : IQuery<TResult>
{
    TResult Handle(TQuery query);
}
public interface IQueryProcessor
{
    TResult Process<TResult>(IQuery<TResult> query);
}

// Messages
public class StudentDto { }
public class FindStudentsByName : IQuery<StudentDto[]>
{
    public string SearchText { get; set; }
}

// Implementations
public class FindStudentsByNameHandler : IQueryHandler<FindStudentsByName, StudentDto[]>
{
    public StudentDto[] Handle(FindStudentsByName query) => new StudentDto[0];
}

public class LoggingQueryHandlerDecorator<TQuery, TResult>
    : IQueryHandler<TQuery, TResult>
    where TQuery : IQuery<TResult>
{
    private readonly IQueryHandler<TQuery, TResult> decoratee;

    public LoggingQueryHandlerDecorator(IQueryHandler<TQuery, TResult> decoratee) 
        => this.decoratee = decoratee;

    public TResult Handle(TQuery query)
    {
        Console.WriteLine($"Handling {typeof(TQuery).Name}");
        return this.decoratee.Handle(query);
    }
}

public class Program
{
    static void Main(string[] args)
    {
        var container = new Container();

        IQueryProcessor processor = new QueryProcessor(container);
        container.Register(typeof(IQueryHandler<,>), typeof(FindStudentsByNameHandler).Assembly);
        container.RegisterDecorator(typeof(IQueryHandler<,>), typeof(LoggingQueryHandlerDecorator<,>));
        container.Verify();

        StudentDto[] result = processor.Process(new FindStudentsByName { SearchText = "Seemann" });

        Console.WriteLine("Number of found students: " + result.Length);
        Console.ReadLine();
    }

    sealed class QueryProcessor : IQueryProcessor
    {
        private readonly Container container;

        public QueryProcessor(Container container) => this.container = container;

        public TResult Process<TResult>(IQuery<TResult> query)
        {
            var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
            dynamic handler = container.GetInstance(handlerType);
            return handler.Handle((dynamic)query);
        }
    }
}


This program does the following:

  • * Defines one single query handler implementation (for searching students by their name

  • * Defines one decorator for query handlers

  • * Auto-registers all query handler that live in the same assembly as FindStudentsByNameHandler (means in this case only that handler is registered)

  • * Registers the decorator to be applied to all query handler abstractions.

  • * Sends a query message to the QueryProcessor.


  • When I run this example on my computer, the output of this program is:

    Handling FindStudentsByName
    Number of found students: 0
    


    There are two things you can do to find your problem:

  • * Either you use this example and add new code incrementally and run often to see wether it keeps working

  • * You reduce functionality of your own implementation in small steps and run often to see when it it starts working to find out where the problem is.
  • The handler should get decorated. Please make sure you are not resolving a concrete type, because in that case Simple Injector can't wrap a decorator. For instance:

    var container = new Container();
    container.Register<IService, Component>();
    container.RegisterDecorator<IService, LogginDecorator>();
    
    container.GetInstance<IService>(); // gets a decorated Component
    container.GetInstance<Component>(); // gets Component directly. Impossible to wrap a decorator
    
    Just wrap the resolve and execution of the query handler into a Scope:

    public TResult Execute<TResult>(IQuery<TResult> query) {
        using (AsyncScopedLifestyle.BeginScope(this.container))
        {
            Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
    	         
            dynamic handler = this.container.GetInstance(handlerType);
    	 
            return handler.Handle((dynamic) query);
        }
    }
    


    Or, you can start a scope on a different level; that's up to you. With the SOLID Services project, every request is wrapped in the scope of an AsyncScopedLifestyle. This ensures that during the time a query handler is resolved, there is an active scope that can be used to resolve scoped instances.
    If you're not reading the book from cover to cover, the glossary will come in handy. It will be located in the back of the book and will point you to the page where terms are defined.

    One caveat though, it could be that the current MEAP of the second edition doesn't have a glossary smilie The final print will, obviously, contain a glossary that lists all important concepts. There will also be a Glossary Conceptual Map inside the front cover that shows a subset of the glossary list that visualizes their relationship with one another.
    The concepts of Stable Dependencies and Volatile Dependencies are defined in sections 1.3.1 and 1.3.2.
    Yuck. I see what you mean. I'm afraid these are MEAP quirks. They will certainly be fixed after we went to print, which will be within a month or two. Please be patient.
    Thank you for reporting this. Rest assured that this (and many, many, many other 'bugs') will be fixed before we go to print.
    > I guess my question is why are they injected at all? How is using DI in this case different than just setting the data context property in main view method?


    There is no difference in this case. Setting DataContext property with the ViewModel is a form of DI, it's Property Injection. Setting the DataContext with the ViewModel is, as far as I know, common practice in WPF and UWP.

    > It more or less comes down to how you like to keep your code organized?


    Splitting UI and PL allows them to live in different assemblies, and can prevent the PL assembly from taking a dependency on assemblies that are only of interest to the UI or Composition Root. In the first edition, the separation between UI and PL was, I believe, introduced in chapter 2. In the second edition, however, we decided to remove the introduction of the PL and with it the separation of those two layers. We felt it wasn't required to effectively tell our story.

    Whether it is useful to make this split, however, depends on how important it is to prevent the assembly that contains the PL code (such as controllers or ViewModels) to have dependencies on the rest of the application.

    > think it also incorrectly uses interfaces? They are all using local defaults, and not really referenced outside their projects.


    Can you give an example? I did a quick browse through the project, but not sure what you are pointing at.

    > I think the controllers are an example of the controlfreak through abstract factories anti-pattern.


    Abstract Factories are not an anti-pattern. Chapter 6, however, does describe that some particular uses of Abstract Factories are code smells. Where do you see the Control Freak?

    > but I don't quite get why the views and VMs can't be tightly coupled, and have the VMs created with injected dependencies.


    A ViewModel in MVVM is always tightly coupled with its view, j

    In chapter 7, ViewModels are actually injected into the view. You can see this in the book's code downloads, but Listing 7.6 (latest MEAP version) shows this as well. The CreatePage method of the App.xaml.cs. Here you see that the ViewModel is injected into the View's DataContext property. So Property Injection is used and the ViewModel is a dependency of the View.

    Furthermore, as the XAML of the MainPage of Listing 7.5 shows, Views are tightly coupled with the ViewModel. They are perhaps not *strongly* coupled, since there is no compile-time support, but they certainly are *tightly* coupled, since the XAML uses properties of that specific ViewModel.

    > What is a scenario where you'd want to inject a different VM?


    You don't. You never want to do that.

    > In the DI first edition, it looks like the VMs and views are in separate projects and use a factory and adapter - is that still suggested?


    No, the use of factories presents an extra level of indirection that is typically not required. I would advise following the 2nd edition's UWP guidance while building WPF applications. There are some differences between the two, but from a DI perspective, this wouldn't be that much.

    > I'm a little confused about what goes in each layer, and the best way to design this in a way that I could replace the WPF app with a web app in the future

    > For the UI layer, should that have only the views, or the ViewModels as well?


    That's actually a pretty hard to answer question. In the first edition, UI and presentation layer are separated, which might be a good thing to do when your application gets bigger. On the other hand both the UI and PL will be specific to WPF. You can throw them away completely when moving to a web application.

    Important, however, is to keep your domain and DAL separated. In that respect, chapter 10 will probably be of a lot of help in designing that part of the application.

    > isn't doing `IEnumerable<DiscountedProduct> featuredProducts = ...` in HomeController tightly coupling the UI and DAL?


    No. DiscountedProduct is defined in the domain layer, so this tightly couples the UI with the domain layer, but that would unlikely be a problem, since the domain is the core part of your application. For a more elaborate discussion, see the "Dependency Inversion Principle" section of section 3.1.2.

    > what was the reasoning in removing the WPF chapters in the second edition?


    Reasoning was that in this edition we are targetting .NET Core related technologies specifically, and WPF was already discussed in the first edition, which comes as free PDF with your purchase. Most of the advice given in 7.2, however, is applicable to WPF as well.

    > or the data access and domain layers, I think I understand where things should go, let me know if I have this right:


    Your description seems pretty accurate, which implies that we did a good job in describing it smilie

    > what exactly is considered business logic


    This actually is a bit fuzzy, and during the lifetime of your project, you will from time to time get into discussions over where a piece of logic should reside. In chapter 2, we state the following (last paragraph of 2.1.2):

    Domain logic is all the behavior that the application needs to have, specific to the domain the application is built for.


    So when that behavior is specific to the domain, the domain layer is where to put it.

    If you want to learn more about building complex domains, Eric Evans' book "Domain-Driven Design: Tackling Complexity in the Heart of Software" (Addison-Wesley, 2004) is a great place to start.

    > what service means vs a controller.


    "Service" is an awfully broad term. In chapter 1 we state:

    In DI terminology, we often talk about services and components. A service is typically an Abstraction, a definition for something that provides a service. An implementation of such Abstraction is often called a component, a class that contains behavior.


    In the context of the ProductService of chapter 2 and 3, however, the service postfix is used to state that it is part of the domain layer. This is a very common practice, and in this case the name does not imply an abstraction, but just something that provides a service. As you'll learn in chapter 10, however, such design for services often isn't the most ideal.

    Controller as well can mean several things. In the book the term controller typically refers to the controller of the Model-View-Controller (MVC) pattern. In that case, "MVC controllers are responsible for responding to requests made against an ASP.NET MVC website. Each browser request is mapped to a particular controller." (source: https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/aspnet-mvc-controllers-overview-cs)

    > Is there a good resource that would list those common definitions?


    Many of those pattern names come from Martin Fowler's book "Patterns of Enterprise Application Architecture" (Addison-Wesley, 2003)

    > Or should I just wait till the glossary is done?


    The glossary will not contain descriptions for terms like service, controller, repository, decorator, and other patterns. The glossary will only contain the book's terminology words (in the MEAP printed as bold), which include patterns like Composition Root, Constructor Injection, and Singleton Lifestyle, anti-patterns like Service Locator and Ambient Context, and common design principles such as the SOLID principles and CQS.

    I hope this helps
    You can use a wide range of tools to create diagram, such as Microsoft Visio or PlantUML (which is a DSL for describing UML in a text-bases DSL, see: http://plantuml.com/). For the MEAP, we used Lucidchart, which is a (payed) online tool for creating charts and diagrams.
    We are actually discussing this with Manning at the moment. Mark and I also feel that changing the book's title would make it more clear that it not just for .NET developers. This discussion, however, is ongoing. No decision has been made about the book's title yet.
    Thank you for reporting this. I will report this with Manning, but note that it might take some time for them to fix this. In the meantime, you can look up the figures in your PDF download.
    I'm unsure why this would violate the SRP, but there are a few things to note here:

    - When we look at the concept of Aggregate Roots from DDD, we would only have repositories on the Aggregate Root. Since an Order Line has no use by itself, it is part of the Aggregate of entities, with Order as its Aggregate Root. So it would be up to the OrderRepository to store the order lines as well, and it could do so transactionally.
    - Chapter 10 shows how you can apply a transaction around business operations using a TransactionScope. In that case, everything within that scope runs within the same transaction. This solves the problem of having multiple individual updates of your database, or multiple calls to DbContext.SaveChanges.
    Hi,

    Sorry for my late response. We've been quite busy getting the book ready for print.

    First what I am missing is what happened now to the repository interfaces and implementations. Should these also change to SRP.


    That's actually a hard question to answer, because it will typically depend a lot on the system you are building. What I found, however, is that from the query side of things, query handlers (e.g. `IQueryHandler<TQuery, TResult>`) effectively replace the use of repositories. If we look at this from the point of view of an MVC Controller, for instance, you won't find any GET action to use a repository abstraction, they will solely use a query handler.

    From a domain's perspective, things might be different though. The logic inside a command handler (which will typically contain domain logic), might still use repository interfaces, although you should definitely be conscious of any maintainability issues that might be caused by wide interfaces, which is something that might happen when you start applying cross-cutting concerns around those abstractions.

    In the Listing in chapter 10 and the decorators. Like auditing security, there is no repository injected instead the CommerceContext is directly injected. This confused me because now the domain layer would have again a dependency to the data access layer.


    One of the shown command handlers in chapter 10 accidentally depended on CommerceContext. This is an error and will be fixed before we go to print. This is a DIP violation.

    Having a decorator depend on the CommerceContext, however, will not be a problem when the decorator is part of the Composition Root. The Composition Root depends on all other modules in the system anyway. If, however, you need to place that decorator in the Domain Layer, you will have to refactor the dependency on CommerceContext, because otherwise the Domain Layer would require a dependency on the Data Access Layer.

    I for my part think that service and repository interface should also be not in the same assembly, am I right?


    Since it is the Domain layer that uses the repository interfaces, the DIP states that it should own that interface. This typically means placing the interface inside the same assembly. It is possible to place the repository interfaces in a different assembly, but there should be a benefit of doing so. For instance to be able to deploy the Domain Layer and Data Access Layer separately. Deploying the DAL without the DL, however, typically makes no sense, because the DL is the heart of the application, and it is always needed.

    The last problem I have is with implementation of POCO's, which depends on each other (e.g. order and items). What for me is important is especially an approach with Transaction in mind. So, when something went wrong there is a rollback for the order and all its items. Next to find and inform the right warehouse, inform the billings system when products are ordered, there has to already a change in the disposition within the scope of the transaction.


    For any distributed system, transactional consistency is an illusion. Any time your application needs to communicate with a different system (e.g. billing, warehouse, etc.) you can't really have those systems perform that operation in a single transaction. Doing so would cause a distributed transaction, and this has many negative consequences.

    The solution to this problem is Eventual Consistency, which is what chapter 6 is hinting at with its use of Domain Events. When we use Eventual Consistency rather than distributed transactions, any single application in the distributed system will ensure that its data is stored in such way that it won't lose any data, preferably with transactions. For instance, both the publication of the Domain events and the changes to its internal database will be transactional. So what this means is that once the OrderApproved Domain Event is stored in the durable queue (which could be a database table), we will not yet have notified Accounting and Billing, but those systems will *eventually* be notified. When the notification succeeds, the applications will be consistent again.

    This whole concept of Eventual Consistency is very important when you start working with either distributed systems or when applying Domain Events. A discussion about this, however, was outside the scope of this book.

    I hope this makes sense.




    foobar
    Thank you for your comment.

    We are aware that the readability of the annotations on the figures is currently not great. This is because of the size, color and type of font we used, while the low image resolution also plays a part. This is something that will certainly be fixed before we go to print.

    Whether a Volatile Dependency is simple or not, does not change the fact that it still is a Volatile Dependency. And although some might argue that there is no such thing as too much logging, I would argue the other way around. The systems I've helped design the last say 8 years never had lines of logging code spread out through the vast majority of classes in the system. We did log, and we were able to log more by increasing the verbosity level, but we typically had a handful of classes in the system that actually did the logging. So the most important point here is: you might want to log a lot, but that doesn’t mean you should have logging statements spread out through the system “like a disease”.

    Here are some pointers that I always watch out for:

  • - Smell: Having method entry and exit logging statements. (Probable cause: missing good abstractions, see chapter 10)

  • - Smell: Logging in places that should have been exceptions (probable cause: not truly understanding the domain, or being afraid to throw)

  • - Smell: Logging exceptions and re-throwing them (probable cause: missing top-level catch that logs errors)


  • I like to, again, emphasize that a good design, for the most part, prevents logging from spreading "like a disease". Chapter 10 provides some clues on what type of design can help in preventing cross-cutting concerns like logging from spreading like a virus. Chapter 10 is not a complete answer to this, however. For instance, it indeed doesn't explain how to decorate other parts of the systems (i.e., your queries), but the chapter does reference a blog post that actually does describe this. The chapter is not meant to describe a full end-to-end solution to design your complete application with. That by itself would take a complete book to describe. The chapter, however, tries to give you an idea of how to model your system, and what good abstractions would be.

    The book, however, describes other (related) patterns that help in increasing maintainability. One of these patterns is Domain Events (see section 6.1.3), additionally with the use of durable queuing (see the last sidebar of section 6.1). Domain Events allow for an even more fine grained design, which gives even more options in pulling logging into the application’s infrastructure (e.g. using decorators), and even allows the handling of events to be scheduled, queued, retried, and… logged.

    This story, however, might be very uncomfortable, because, most likely, fixing the disease-like design is a big design change, which is likely to be a lot of work. And it’s not only a matter of design, but coding practices and habits as well, which is probably just as hard to change.

    But this is obviously how things work: new insights happen all the time, and you will have to determine whether this change is feasible for your application at this point in time. But as we stated at the introduction of chapter 5:


    In some cases, an anti-pattern might be the most appropriate _temporary_ solution. Even though the application of an anti-pattern might be an improvement over the original code, it is important to note that this doesn't make it any less an anti-pattern, because another documented and repeatable solution exists that is proven to be more effective.


    logging is an exceptional case. It's cross cutting concern.


    I would argue that logging is -not- an exceptional case. There are many Volatile Dependencies in our system and we have to deal with Cross-Cutting Concerns all the time. What makes this particular Cross-Cutting Concern so different and exceptional to all other Dependencies and Cross-Cutting Concerns that we accept the downsides that Ambient Context brings?

    Is it perhaps that we need it all over the place -or- at least we think we do?


    it's a hassle to pass an ILog instance on every object that needs to write a couple of lines in the logs.


    That's great, because it -should- be a hassle. That means your design is telling you something. The hard part however is figuring out what exactly it is telling you. But my gut feeling is that you log at too many places in your application.

    We addressed this in this callout:


    IMPORTANT By no means we are stating that you shouldn’t log. Logging is a crucial part for any application, as it is in the applications we build. What we are saying however is that you should design your application in such way that you only a handful of classes in your system are affected by logging.


    But now the question obviously becomes, how exactly should you design your system in such way that you can minimize the amount of log statements? There are many answers to this, but as we hinted in section 5.3, chapter 10 goes into great length to demonstrate an application design that can help with these kinds of issues.

    Did you already read chapter 10?
    Hi Stelios,

    I'm sorry we couldn't convince you on this. We've given all the arguments on why it is a bad idea in the book, so I won't be repeating it again here.

    You probably read the first edition a long time ago, but even in the first edition, you can read between the lines that, at that time, Mark already thought that the use of Ambient Context should be really rare, and that in general there are better solutions.

    Over the years, Mark and I both came to the conclusion that there are _always_ better solutions, which is why we decided to explicitly state Ambient Context as an anti-pattern. We realized, however, that there was the risk of offending people, since this is a _very_ common pattern. That's why chapter 5 gives two examples of widespread Ambient Context use, while describing better alternatives. Whether you take our advice or not, is completely up to you.
    Hi,

    As we state in chapter 5, any use of a DI Container, inside the Composition Root is good use, and does not imply the Service Locator anti-pattern. So as long as this piece of infrastructure is part of your Composition Root, it is fine. If it's not part of your Composition Root, consider moving it into the Composition Root.

    This doesn't mean that you should move all the messaging infrastructure code into the Composition Root, but just the part that requires knowledge of the DI Container or an abstraction over it.
    Whether or not IProductService violates the RAP depends on whether we will have other implementations. In later chapters we show how to add cross-cutting concerns using Decorators on top of IProductService. At that point, IProductService stops violating the RAP.

    IProductService serves other purposes than just enabling testing, and this basically comes back to the advantages of DI, as discussed in chapter 1—testability is just one of them.
    Your observation is correct. IProductService does violate the DIP. To fix this violation there are a few options, such as moving IProductService to the Presentation Layer, or moving this interface to a separate project that only contains Domain Layer abstractions.

    Moving the interface to the Presentation Layer would obviously cause problems, because it would make the Domain Layer specific to the used presentation technology, which disallows it to be reused. Besides, as long as the Composition Root would be placed in the same assembly as the Presentation Layer, a cyclic dependency between the assemblies would exist, as you so rightfully point out.

    Moving the interface to a separate "interfaces" project would be the most appropriate solution. We however made the pragmatic decision to put the interface in the Domain Layer project itself, because this would simplify the discussion within the chapter.

    What we omitted however was an explanation about this pragmatic decision, which is something we should add to chapter 3.


    Thank you for reporting this.
    Hi Janus,

    You’ll be glad to hear that we rewrote the advice around Abstract Factories completely in the second edition. The first edition described Abstract Factories as *the* solution any time you needed to deal with the creation of dependencies that depended on runtime data, and any time a dependencies’ lifetime needed to be managed outside the Composition Root. In the second edition, although we still see value in the use of Abstract Factories, we recognize that more often than not, Abstract Factories are over-used, and better solutions are quite often available.

    My advice would be to read chapter 6.2 of the second edition. That part focusses completely around Abstract Factories abuse and described alternative solutions.

    When it comes to DDD and having Domain Entities consume Dependencies, chapter 4.3 of the second edition describes in some detail how Method Injection is the way to go here.

    Although the second edition isn’t finished, if you pre-order it today, you already get the e-book with the first 8 chapters. I hope the already available material will point you into the right direction.

    If you have any questions after reading the second edition, please let me know.


    Cheers


    Steven
    Hi Tomas,

    It is our opinion that DI is not "falling short" when it comes to adding monitoring and tracing to application code. A well-designed application allows plugging in these types of Cross-Cutting Concerns to a wide range of classes, without the need to make sweeping changes throughout your production source code. And yes, this is absolutely desirable!

    This is a subject that is extensively covered in chapter 10. We expect chapter 10 to be published as MEAP version within a month or so.
    Please note that Unity is not dead. Microsoft abandoned this project, but it is currently being actively maintained on Github.

    Besides, there are other alternatives besides Autofac, such as Simple Injector (https://simpleinjector.org) (which is maintained by myself).

    This is a topic that will be discussed in detail in chapter 10 "Aspect-Oriented Programming". The short answer is, that there should likely exist no OrderService class at all in your application (since that violates OCP, SRP, and ISP), but only service classes with one public method. So you should typically have a CancelOrderService, ApproveOrderService, ShipOrderService, MakeOrderService, etc.

    I won't go into more details here, since chapter 10 spends about 30 pages on this exact topic. So this is a major teaser, but you'll have to wait until chapter 10 :-/
    I just fixed this in our repository. It might take some time for those changes to be reflected in the downloads though.

    Thanks for reporting this.
    Thanks for your comment.

    The extra arrow from UI to Data in figure 2.6 is added for illustrative purposes, but in fact such arrow is redundant, since project dependencies are transitive, which means that when project A depends on B, and B depends on C, it implies that A depends on C as well.

    That's why in chapter 3 we choose again to use the simplified form where the arrow between UI and Data is not visible, but it is still there; the dependency is implied.

    However, the theory about transitivity is explained in chapter 4 (see "The apparent dependency explosion"), not in chapter 3. Because of this, it might be good to make the dependency more explicit. We'll reconsider adding that arrow.

    Thanks for your feedback.
    I just fixed this in our repository. It might take some time for those changes to be reflected in the downloads though.

    Thanks for reporting this.
    Try contacting Manning through their support channel: https://www.manning.com/support
    The book is today (Oct 24) deal of the day. You can get it 50% of when using the code dotd102417tw at https://www.manning.com/dotd.

    This deal expires in 13 hours.
    We decided not to cover Unity. We mainly decided to only cover:

    - Popular DI Containers
    - That are .NET Core and .NET Standard compatible
    - That are actively maintained
    - And not already discussed in the first edition.

    We decided to exclude containers discussed in the first edition, since a digital copy of the first edition will be supplied with your copy of the second edition.

    The exception that we took here was to keep Autofac in, because it is by far the most popular, actively maintained, .NET Core compatible container in the field.

    Note the following obvious warning: This book hasn’t been released yet, so keep in mind that the decision on which container to include can still change.
    Hi James,

    The main motivation for us was to be able to be able to share our new knowledge with a broad audience. Although blog posts, presentations and Pluralsight videos allow us to get this message across, there is no medium as suited to get a complicated story across as a book.
    Since writing a new book is a major undertaking, Mark has asked me to help him with this. It was simply too much to chew off for Mark alone.

    What will not change:
    The second edition will still be solely about implementing DI in statically types object-oriented languages. Examples are still just in C#. Functional Programming has its own patterns and practices and that would deserve a book of its own.
    Each chapter will still start with a cooking analogy.

    What will change:
    The second edition focusses even more on patterns & practices than the first edition did. There are several areas you will notice this.


    * First of all, the discussion of DI Containers is completely moved to Part 4. The first 3 parts of the book will be completely container agnostic.
    * More examples are added and many parts are completely re-written throughout the book.
    * Ambient Context is now considered an anti-pattern and we describe in detail why that is.
    * The original refactoring chapter (6) is almost completely rewritten, and now describes code smells.
    * We added new sidebars and new sections where we warn about bad practices and bad design decisions.
    * We start referring to the SOLID principles much earlier in the book (in the first edition they were first mentioned in chapter 9).
    * We removed some complexity and ambiguity in the book's running code samples. This allows the reader to focus more on applying the patterns and practices.
    * The Interception chapter (9) is rewritten for the most part. We added this much information that we decided to split up the chapter in three distinct chapters (9, 10, 11). In chapter 9 we focus on the Decorator pattern as method of interception.
    * Chapter 10 contains complete new material discussing how to apply AOP based on the SOLID design principles. In many ways, we consider chapter 10 to be the climax of the book.
    * Chapter 11 focusses on applying AOP using tooling such as dynamic interception and compile-time weaving tooling. This information was available in chapter 9 of the first edition, but we elaborated the discussion to explain all the downsides that these approaches have compared to the methods described in chapter 10.
    * We now consider compile-time weaving a DI anti-pattern and chapter 11 describes in detail why compile-time weaving is a bad practice when it comes to applying Volatile Dependencies.
    * Chapter 12 describes the basics of DI Containers and goes into details how to choose between Pure DI and a DI Container. This chapter is an updated version of chapter 3 of the first edition.
    * This edition discusses three DI Containers, which are Autofac, Simple Injector, and Microsoft.Extensions.DependencyInjection. Each container gets its own chapter, and although these chapters are based on the first edition, they also describe how to use those containers in combination with concepts described in this edition, such as the "AOP by design" approach, laid out in chapter 10.
    * Chapter 15 describes the Microsoft.Extensions.DependencyInjection container, and discusses in much detail what the limitations and downsides of this simplistic DI Container implementations are, while we do show how to work around some of its limitations.


    With the help of Manning’s readability experts, the second edition will now do an even better job to get the message across.

    The book focusses on .NET Core and its frameworks. Although there is still a lot of code that works for any .NET version, especially the parts that show how to integrate (most notably chapter 7), are focused on .NET Core and ASP.NET Core.
    We incorporated many of the lessons we learned and knowledge we gained after the first edition was published. This will sometimes manifest itself in small notes or warnings, up to sidebars or even complete sections or chapters.

    Note the following obvious warning: This book hasn’t been released yet, so keep in mind that everything written above could still change.
    You'll need Visual Studio 2017 to compile the code.

    Currently the sample applications are built using ASP.NET Core 1.0, but you can expect the solution to be upgraded to ASP.NET Core 2.0 in the future.
    Thanks.

    I will pass this along to the MEAP team.
    Hi Tony,

    Thanks for reporting this. I verified this, and unfortunately have to admit the figures are a mess. Almost all figures are on a wrong page with an incorrect number. On top of that, these figures are from the first edition, while we redone them for the second edition.

    I've passed this on to the publishing department and asked them to fix this a.s.a.p.

    I'm sorry for the inconvenience.
    I'm pleased to announce that this anomaly will be fixed in the second edition. You can find the fix in chapter 3 of the second edition: https://manning.com/seemann2/
    Hi Tom,

    Yes there are examples. Chapter 3 of the book shows some examples and the source code contains a fully runnable example of this. The source code is available for download on the book's main page: https://manning.com/seemann2/


    Steven
    Thanks. We will fix this.
    I'm unsure whether there is a special discount for first edition owners, but there is an "early bird" discount if you purchase the book before May 5.

    You can get a 50% discount if you use the following discount code:

    mlseemann2

    HTH