NDepend

Improve your .NET code quality with NDepend

Static Analysis and Dependency Injection

For quite some years now, we (the NDepend team) got some demand about resolving Dependency Injection, see this page on our User Voices. Lately we’ve been considering such support carefully but came to the conclusion that it’d be awkward. On the other hand we have alway been prioritizing features development based on user feedback and need. So our conclusions are not definitive yet. I write this post to not only expose our point of view, but eventually trigger more productive discussions.

Static Analysis

First let’s underline that NDepend is a static analyzer. It gathers 100% of its data from the code itself, and also parses more data like code coverage. Static analysis is in opposition with dynamic analysis that gathers data from runtime execution.

  • Static analysis deals with classes, methods and design measures like lines of code or complexity. It is design-time analysis.
  • Dynamic analysis deals with objects and runtime measures like performance or memory consumption. It is run-time analysis

Dependency Injection (DI)

Recently I explained the basis of Dependency Injection (DI) and how it relates to DIP in the post SOLID Design: The Dependency Inversion Principle (DIP). DI is all about depending on interfaces instead of depending on classes. Here is simple DI sample code, ClientCode() depends on IDbConnection and not on SqlConnection. The power of DI is that now ClientCode() can run on other RDMS than SQL Server, like Oracle or SQLLite. ClientCode() can now also be unit-tested seamlessly by mocking the interface IDbConnection.

Stable Dependency Principle (SDP)

DI is an application of the Stable Dependency Principle (SDP), which is not part of the SOLID principles, but is much related with the Dependency Inversion Principle (DIP).

SDP states: The dependency should be in the direction of the stability. Stability is a measure of the likeliness of change. The more likely it will change, the less it is stable.

The Liskov Substitution Principle (LSP) and the Interface Segregation Principle (ISP) articles explain how interfaces must be carefully thought out. As a result an interface is a stable code element, that is less likely to change than the the classes that implement it. Following the SDP, it is better design to rely on interfaces than to rely on concrete classes.

The Users need: supporting DI through Static Analysis

In this context, users want NDepend to be able to parse DI code like that.

Concretely users want NDepend to bind all calls to an IDbConnection member with a call to the corresponding SqlConnection member . For example a dependency toward SqlConnection.Open() should be created for any method calling IDbConnection.Open().

But why would this be useful? Here is a user feedback:

We have layered architecture: Foundation, Feature, Project. Following current NDepend report, everything follows right dependencies. Project depends on Feature and Foundation. Feature depends on Foundation. However due to some of DI registrations, we have complex dependencies (…) there is dependency from Foundation to Project in reality. Interface is declared in Foundation, but implementation is in Project and registered via DI. It means that Foundation projects, that are core and stable part of solution, depend on Project level, which is not so stable and reliable.

In reality is highlighted in bold, because the user really meant at run-time. At run-time Foundation depends on Project, the same way that at run-time ClientCode() depends on SqlConnection. But at design-time Foundation doesn’t depend on Project, the same way that at design-time ClientCode() doesn’t depends on SqlConnection. At design-time ClientCode() only knows about IDbConnection.

From this, one implies that not only at design time, but also at runtime dependencies should go from Project towards Foundation. In other words, one feels that implementing an adapter into Project and injecting it into a Foundation component “is not so stable and reliable”, but that’s not how those principles are meant and described.

As a matter of fact, being able to inject Project adapters into Foundation components (where the Project adapter implements one of Foundation’s interfaces) is the core of the Dependency Inversion Principle (DIP). Without it, it is impossible to create flexible systems. This can be unreliable, but only if one doesn’t follow the Liskov Substitution Principle (LSP), when Foundation interfaces are not well thought-out, like for example when ICollection<T> forces the Array class to implement ICollection<T>.Add() which obviously cannot be supported.

Conclusion

Hence it looks like this feature need results from a confusion between design-time dependencies and run-time dependencies. The purpose of design is to reduce the cost of change, anything else is not design. Managing design-time dependencies is at the heart of design. All SOLID principles and all principles surrounding SOLID like the Stable Dependency Principle (SDP) are about design-time dependencies.

Moreover adding DI support would be a never-ending story—and I guess it cannot be done right without information collected at run-time. DI Containers are very complex beasts internally, their behavior often changes from one major version to the next, and there are dozens of DI Containers in .NET (Autofac, UnityContainer, NInject, StructureMap, MEF, SimpleInjector, Castle.Windsor, LightInject, Prism, Spring.net … just to name a few).

Again all our developments are driven by users-need, but on this particular need we’re not sure it’d make sense. We let the discussion open on this post and on the User Voices page. Whether you agree or disagree with our positions, feel free to comment.

 

 

domain_driven_design_demystified

Domain-Driven Design Demystified

Domain-driven design, or DDD, is a software design methodology aimed at producing better software. Engineers achieve this by working closely with domain experts during the continuous design process.

Eric Evans created domain-driven design and wrote a book about the practice called Domain-Driven Design: Tackling Complexity in the Heart of Software. His main points are to use models, use the language of the business, and follow specific technical patterns during development. Together, these steps will help you deal with complex software without painting yourself into a corner.

In this post, I’ll go further into demystifying domain-driven design. First, I’ll share a story about how I came to know the practice myself. Then I’ll get into some details about the modeling part of the process. Finally, I’ll do an overview of the technical bits of the craft.

Continue reading Domain-Driven Design Demystified

Checking DDD Ubiquitous Language with NDepend

Since NDepend version 2018.1, the tool proposes a default rule to check Domain Driven Design (DDD) Ubiquitous Language validity.

DDD Ubiquitous Language

Let’s quote Martin Fowler on Ubiquitous Language:

Ubiquitous Language is the term Eric Evans uses in Domain Driven Design for the practice of building up a common, rigorous language between developers and users. This language should be based on the Domain Model used in the software – hence the need for it to be rigorous, since software doesn’t cope well with ambiguity.

Evans makes clear that using the ubiquitous language between in conversations with domain experts is an important part of testing it, and hence the domain model. He also stresses that the language (and model) should evolve as the team’s understanding of the domain grows.

–Martin Fowler

Eric Evans coined the term DDD, let’s quote him:

By using the model-based language pervasively and not being satisfied until it flows, we approach a model that is complete and comprehensible, made up of simple elements that combine to express complex ideas.

Domain experts should object to terms or structures that are awkward or inadequate to convey domain understanding; developers should watch for ambiguity or inconsistency that will trip up design.

–Eric Evans

See below a sample of ubiquitous language usage in the real-world. We end up with clean and readable code:

The TrainTrain Code Base

To explain and demonstrate the rule, we’ll conduct our experiment on the TrainTrain code base.

This OSS code base has been developed by Bruno Boucard and Thomas Pierrain from 42Skillz, a French consultancy company specialized in DDD and developers coaching. TrainTrain has been developed in order to illustrate concretely most of DDD concepts (including Ubiquitous Language) in a session named How To Distill The Core Domain From Your Legacy App (Live Coding). In this session, a legacy version of the code is live-refactored to a DDD-compliant version. It has been performed both at Explore DDD 2017 (Denver, Sept 2017) and DDD Europe 2018 (Amsterdam, Jan 2018).

We worked with Bruno and Thomas to develop this first rule related to DDD and we expect that more rules will follow from this collaboration.

The Rule

See below the full source code of the new rule named DDD ubiquitous language check that can be found in the rule group Naming Convention. This rule is disabled by default because before using it, the user must customize both:

  • The core domain namespace name (by default set to “TrainTrain.Domain”)
  • The vocabulary list

The idea is to centralize in this rule source code the vocabulary. The rule then checks that all code elements defined in the core domain namespace are named with one or several terms found in the vocabulary list. Code elements checked include classes, enumerations, structures, interfaces, methods, properties and fields. If a term needs to be used both with singular and plural forms, both forms need to be mentioned, like Seat and Seats for example.

The NDepend rule system makes easy to modify the source code of an existing rule. There is no Visual Studio project to create and store, no NuGet package to reference, no assembly to compile, version and maintain, no integration. Just textual edition with code completion, API documentation and live result while editing, and then Ctrl+S, that’s it. As a consequence, the NDepend rule system is well suited to implement such rule that must be customized with some user data before usage.

Notice that this rule relies on the new NDepend API method ExtensionMethodsString.GetWord(this string identifier). This method extracts words from code identifiers. For example from the field identifier _seatsRequestedCount it extracts the 3 words seats, Requested, Count. To be compliant with the vocabulary list, we then set the first char to upper, for example seats becomes Seats.

Running the Rule

See below a screenshot on running this rule on a TrainTrain version. An issue is spotted on a core domain class named TreasholdCapacity. Both words are reported in the column wordsNotInVocabulary because both words are not in the vocabulary list. Moreover the word Treashold has a typo. At this point, to fix this issue:

  • either this class should be renamed with existing core domain vocabulary words
  • either these words should be added to the vocabulary list (with the typo fix)

 

DDD is nowadays a popular concept. We are proud to innovate with a static analysis code rule related to DDD. We have plans for more DDD related rules and we would like to hear both your feedback on using this rule, and your needs for more DDD related rules.