HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcsharpMinor

How can I make this C# code better so it more closely follows DDD principles? Am I using factory correctly?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thisprinciplescandddfactorymakemorebetterfollowsusing

Problem

I've been working on converting some legacy code from T-SQL stored procedures. My aim is to use DDD to make the transition. Below is an attempt to do this. Any comments on how well this is following DDD? Also any comments on the AreaGeneration domain service and its CalculateLocationsInArea would be most appreciated.

```
//consumer code

var locationRepository = new LocationRepository();
//areaGenerator is a domain service which is used to calculate locations between a from and to location
var areaGenerator = new AreaGenerator(locationRepository);
var areaParameters = new List
{
new AreaParameter("A001A", "A002B", AreaDirection.Column),
new AreaParameter("A001A", "A003C", AreaDirection.Row)
};
var locations = areaGenerator.CalculateLocationsInArea(areaParameters);
var area = Area.CreateArea("Test Area", "Special Area",areaParameters,locations);

public class Location
{
public string LocationCode { get; set; }
public int LocationID { get; set; }
public int Aisle { get; set; }
public int Column { get; set; }
public int Row { get; set; }

public string SortKey
{
get { return Aisle + "," + Column + "," + Row; }
}
}

public class AreaParameter
{
public AreaParameter(string fromLocation, string toLocation, AreaDirection areaDirection)
{
StartLocation = fromLocation;
EndLocation = toLocation;
AreaDirecton = areaDirection;
}

public string StartLocation { get; private set; }
public string EndLocation { get; private set; }
public AreaDirection AreaDirecton { get; private set; }
}

public class AreaGenerator
{
private readonly ILocationRepository _locationRepository;

public AreaGenerator(ILocationRepository locationRepository)
{
_locationRepository = locationRepository;
}

internal IEnumerable CalculateLocationsInArea(List areaParameters)
{
var locationsInArea = new List();

foreach (var areaDetail in areaParameters

Solution

I do like what you've done here. I'm a big fan of immutable objects and interface-based programming (for dependency injection, mocking via unit tests, etc.), so I've done a little squidging to make those happen as per below:

```
// consumer code
var locationRepository = new LocationRepository();

// areaGenerator is a domain service which is used to calculate locations between a from and to location
var areaGenerator = new AreaGenerator(locationRepository);
var areaParameters = new AreaParameterList
{
{ "A001A", "A002B", AreaDirection.Column },
{ "A001A", "A003C", AreaDirection.Row }
};
var locations = areaGenerator.CalculateLocationsInArea(areaParameters);
var area = Area.CreateArea("Test Area", "Special Area", areaParameters, locations);

Console.WriteLine("Area Name: " + area.AreaName);
Console.WriteLine("Area Description: " + area.AreaDescription);
Console.WriteLine("Area Parameters:");
foreach (var parameter in area.AreaParameters)
{
Console.WriteLine("\tStart Location: " + parameter.StartLocation);
Console.WriteLine("\tEnd Location: " + parameter.EndLocation);
Console.WriteLine("\tDirection: " + parameter.AreaDirection);
Console.WriteLine();
}

Console.WriteLine("Locations in Area:");
foreach (var location in area.LocationsInArea)
{
Console.WriteLine("\tLocation Code: " + location.LocationCode);
Console.WriteLine("\tLocation ID: " + location.LocationID);
Console.WriteLine("\tAisle: " + location.Aisle);
Console.WriteLine("\tColumn: " + location.Column);
Console.WriteLine("\tRow: " + location.Row);
Console.WriteLine();
}

Console.ReadLine();

public enum AreaDirection
{
Column,

Row,

ALL
}

public interface ILocation
{
string LocationCode { get; }

int LocationID { get; }

int Aisle { get; }

int Column { get; }

int Row { get; }

string SortKey { get; }
}

public sealed class Location : ILocation
{
private readonly string locationCode;

private readonly int locationId;

private readonly int aisle;

private readonly int column;

private readonly int row;

public Location(string locationCode, int locationId, int aisle, int column, int row)
{
this.locationCode = locationCode;
this.locationId = locationId;
this.aisle = aisle;
this.column = column;
this.row = row;
}

public string LocationCode
{
get
{
return this.locationCode;
}
}

public int LocationID
{
get
{
return this.locationId;
}
}

public int Aisle
{
get
{
return this.aisle;
}
}

public int Column
{
get
{
return this.column;
}
}

public int Row
{
get
{
return this.row;
}
}

public string SortKey
{
get
{
return this.aisle + "," + this.column + "," + this.row;
}
}
}

public interface ILocationList : IList
{
void Add(string locationCode, int locationId, int aisle, int column, int row);
}

public sealed class LocationList : List, ILocationList
{
public void Add(string locationCode, int locationId, int aisle, int column, int row)
{
this.Add(new Location(locationCode, locationId, aisle, column, row));
}
}

public interface IAreaParameter
{
string StartLocation { get; }

string EndLocation { get; }

AreaDirection AreaDirection { get; }
}

public sealed class AreaParameter : IAreaParameter
{
private readonly string startLocation;

private readonly string endLocation;

private readonly AreaDirection areaDirection;

public AreaParameter(string fromLocation, string toLocation, AreaDirection areaDirection)
{
this.startLocation = fromLocation;
this.endLocation = toLocation;
this.areaDirection = areaDirection;
}

public string StartLocation
{
get
{
return this.startLocation;
}
}

public string EndLocation
{
get
{
return this.endLocation;
}
}

public AreaDirection AreaDirection
{
get
{
return this.areaDirection;
}
}
}

public interface IAreaParameterList : IList
{
void Add(string fromLocation, string toLocation, AreaDirection areaDirection);
}

public sealed class AreaParameterList : List, IAreaParameterList
{
public void Add(string fromLocation, string toLocation, AreaDirection areaDirection)
{
this.Add(new AreaParameter(fromLocation, toLocation, areaDirection));
}
}

public sealed class AreaGenerator
{
private readonly ILocationRe

Code Snippets

// consumer code
        var locationRepository = new LocationRepository();

        // areaGenerator is a domain service which is used to calculate locations between a from and to location
        var areaGenerator = new AreaGenerator(locationRepository);
        var areaParameters = new AreaParameterList
        {
            { "A001A", "A002B", AreaDirection.Column },
            { "A001A", "A003C", AreaDirection.Row }
        };
        var locations = areaGenerator.CalculateLocationsInArea(areaParameters);
        var area = Area.CreateArea("Test Area", "Special Area", areaParameters, locations);

        Console.WriteLine("Area Name: " + area.AreaName);
        Console.WriteLine("Area Description: " + area.AreaDescription);
        Console.WriteLine("Area Parameters:");
        foreach (var parameter in area.AreaParameters)
        {
            Console.WriteLine("\tStart Location: " + parameter.StartLocation);
            Console.WriteLine("\tEnd Location: " + parameter.EndLocation);
            Console.WriteLine("\tDirection: " + parameter.AreaDirection);
            Console.WriteLine();
        }

        Console.WriteLine("Locations in Area:");
        foreach (var location in area.LocationsInArea)
        {
            Console.WriteLine("\tLocation Code: " + location.LocationCode);
            Console.WriteLine("\tLocation ID: " + location.LocationID);
            Console.WriteLine("\tAisle: " + location.Aisle);
            Console.WriteLine("\tColumn: " + location.Column);
            Console.WriteLine("\tRow: " + location.Row);
            Console.WriteLine();
        }

        Console.ReadLine();

public enum AreaDirection
{
    Column,

    Row,

    ALL
}

public interface ILocation
{
    string LocationCode { get; }

    int LocationID { get; }

    int Aisle { get; }

    int Column { get; }

    int Row { get; }

    string SortKey { get; }
}

public sealed class Location : ILocation
{
    private readonly string locationCode;

    private readonly int locationId;

    private readonly int aisle;

    private readonly int column;

    private readonly int row;

    public Location(string locationCode, int locationId, int aisle, int column, int row)
    {
        this.locationCode = locationCode;
        this.locationId = locationId;
        this.aisle = aisle;
        this.column = column;
        this.row = row;
    }

    public string LocationCode
    {
        get
        {
            return this.locationCode;
        }
    }

    public int LocationID
    {
        get
        {
            return this.locationId;
        }
    }

    public int Aisle
    {
        get
        {
            return this.aisle;
        }
    }

    public int Column
    {
        get
        {
            return this.column;
        }
    }

    public int Row
    {
        get
        {
            return this.row;
        }
    }

    public string SortKey
    {
        get
        {
            return this.aisle + "," + this.column + ",

Context

StackExchange Code Review Q#20883, answer score: 4

Revisions (0)

No revisions yet.