What is Domain Driven Design (DDD)?

ID : 10383

viewed : 36

Tags : domain-driven-designdomain-driven-design

Top 5 Answer for What is Domain Driven Design (DDD)?

vote vote

91

Firstly, if you don't know that you need it then it's possible that you don't need it. If you don't recognize the problems that DDD solves then maybe you don't have those problems. Even DDD advocates will frequently point out that DDD is only intended for large (>6 month) projects.

Assuming that you're still reading at this point, my take on DDD is this:

DDD is about trying to make your software a model of a real-world system or process. In using DDD, you are meant to work closely with a domain expert who can explain how the real-world system works. For example, if you're developing a system that handles the placing of bets on horse races, your domain expert might be an experienced bookmaker.

Between yourself and the domain expert, you build a ubiquitous language (UL), which is basically a conceptual description of the system. The idea is that you should be able to write down what the system does in a way that the domain expert can read it and verify that it is correct. In our betting example, the ubiquitous language would include the definition of words such as 'race', 'bet', 'odds' and so on.

The concepts described by the UL will form the basis of your object-oriented design. DDD provides some clear guidance on how your objects should interact, and helps you divide your objects into the following categories:

  • Value objects, which represent a value that might have sub-parts (for example, a date may have a day, month and year)
  • Entities, which are objects with identity. For example, each Customer object has its own identity, so we know that two customers with the same name are not the same customer
  • Aggregate roots are objects that own other objects. This is a complex concept and works on the basis that there are some objects that don't make sense unless they have an owner. For example, an 'Order Line' object doesn't make sense without an 'Order' to belong to, so we say that the Order is the aggregate root, and Order Line objects can only be manipulated via methods in the Order object

DDD also recommends several patterns:

  • Repository, a pattern for persistence (saving and loading your data, typically to/from a database)
  • Factory, a pattern for object creation
  • Service, a pattern for creating objects that manipulate your main domain objects without being a part of the domain themselves

Now, at this point I have to say that if you haven't heard of any of these things before, you shouldn't be trying to use DDD on any project that you have a deadline for. Before attempting DDD, you should be familiar with design patterns and enterprise design patterns. Knowing these makes DDD a lot easier to grasp. And, as mentioned above, there is a free introduction to DDD available from InfoQ (where you can also find talks about DDD).

vote vote

89

Take StackOverflow as an example. Instead of starting to design some web forms, you concentrate first on doing object-oriented modelling of the entities within your problem domain, for example Users, Questions, Answers, Votes, Comments etc. Since the design is driven by the details of the problem domain it is called domain-driven design.

You can read more in Eric Evans' book.

vote vote

73

Some fallback logic can be added to handle the presence of a Load Balancer.

Also, through inspection, the X-Forwarded-For header happens to be set anyway even without a Load Balancer (possibly because of additional Kestrel layer?):

public string GetRequestIP(bool tryUseXForwardHeader = true) {     string ip = null;      // todo support new "Forwarded" header (2014) https://en.wikipedia.org/wiki/X-Forwarded-For      // X-Forwarded-For (csv list):  Using the First entry in the list seems to work     // for 99% of cases however it has been suggested that a better (although tedious)     // approach might be to read each IP from right to left and use the first public IP.     // http://stackoverflow.com/a/43554000/538763     //     if (tryUseXForwardHeader)         ip = GetHeaderValueAs<string>("X-Forwarded-For").SplitCsv().FirstOrDefault();      // RemoteIpAddress is always null in DNX RC1 Update1 (bug).     if (ip.IsNullOrWhitespace() && _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress != null)         ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();      if (ip.IsNullOrWhitespace())         ip = GetHeaderValueAs<string>("REMOTE_ADDR");      // _httpContextAccessor.HttpContext?.Request?.Host this is the local host.      if (ip.IsNullOrWhitespace())         throw new Exception("Unable to determine caller's IP.");      return ip; }  public T GetHeaderValueAs<T>(string headerName) {     StringValues values;      if (_httpContextAccessor.HttpContext?.Request?.Headers?.TryGetValue(headerName, out values) ?? false)     {         string rawValues = values.ToString();   // writes out as Csv when there are multiple.          if (!rawValues.IsNullOrWhitespace())             return (T)Convert.ChangeType(values.ToString(), typeof(T));     }     return default(T); }  public static List<string> SplitCsv(this string csvList, bool nullOrWhitespaceInputReturnsNull = false) {     if (string.IsNullOrWhiteSpace(csvList))         return nullOrWhitespaceInputReturnsNull ? null : new List<string>();      return csvList         .TrimEnd(',')         .Split(',')         .AsEnumerable<string>()         .Select(s => s.Trim())         .ToList(); }  public static bool IsNullOrWhitespace(this string s) {     return String.IsNullOrWhiteSpace(s); } 

Assumes _httpContextAccessor was provided through DI.

vote vote

63

You can use the IHttpConnectionFeature for getting this information.

var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress; 
vote vote

60

In ASP.NET 2.1, In StartUp.cs Add This Services:

services.AddHttpContextAccessor(); services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>(); 

and then do 3 step:

  1. Define a variable in your MVC controller

    private IHttpContextAccessor _accessor; 
  2. DI into the controller's constructor

    public SomeController(IHttpContextAccessor accessor) {     _accessor = accessor; } 
  3. Retrieve the IP Address

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString() 

This is how it is done.

Top 3 video Explaining What is Domain Driven Design (DDD)?

Related QUESTION?