Can I add a static method in a entity in DDD? - c#

I have a Order entity.
public class Order{
public string OrderNumber{get;set;}
public string CreateDate{get;set;}
......
}
Now, I want to add a getxxx method to it.
public class Order{
public string OrderNumber{get;set;}
public string CreateDate{get;set;}
......
public Order GetOrderDetail(string orderNumber){
.....
}
}
But I do not want to instantiate it every time. So, I want to add static to this method.
Whether this is in compliance with the DDD specification?

There's no reason to have static methods in domain objects except the occasional helper (construction method, property that returns a remarkable specific instance of a Value Object, etc).
If you feel you need it, it's probably a smell that the method is trying to reach for data that is not encapsulated in the entity. It will most likely try to get it from an external source outside the Domain layer and from a tightly coupled dependency, which is problematic in terms of design and testability.

Whether this is in compliance with the DDD specification?
No, it is not.
In DDD we have Repositories that load Aggregate roots, so, considering that Order is an Aggregate root, then you will have to create another class, OrderRepository that has the responsability to load an Order from persistence:
public class OrderRepository{
// ......
public Order loadOrderById(string orderId){
// .....
}
}
P.S. I don't use C#, I hope that this is correct.

In your case the answer is NO.
Reason:
You wont be able to access the non-static public properties of Order class in GetOrderDetail(string orderNumber) method. More likely you will use or prefered to use Dependency Injection
for your Data Access Layer and that DAL object will be a private instance field which wont be accecible in static method.
As the comment from Evk suggests that you wont be able to unit test it.
Here is more information on static methods When to use static classes in C#

Related

How can I fill my rich model from repository when I am no using ORM?

I am trying to develop my application using the DDD approach and I should set all of my properties private. I need to use Aerospike as my database and there is no ORM to fill my properties magically like EntityFramework with a private default constructor.
Now, How can I fill this reach model without exposing a full property constructor that can be accessible everywhere and can breach the rule of encapsulation business domain rules?
making all properties protected and creating an internal inherited class inside the repository namespace that can act as a proxy object to fill property can be a solution But I have no idea about the best practice and acceptable design.
I'm not familiar with Aerospike, but here are my thoughts. First, EF is able to set private properties because it uses reflection to do so. And it needs a parameterless constructor for this. So you could do it the same way: create an object and set properties via reflection.
Or, as others pointed out in the comments, you will anyway need methods to set your private properties, so just use them to instantiate your model. You use private setters and methods in order to ensure that the state of your DDD object is valid and do some internal checks, e.g.:
public class Whatever {
private int age;
public int Age { get; private set; }
public void UpdateAge(int a) {
if (a > 0) {
this.age = a;
}
throw new MyException();
}
}
So just use UpdateAge() and the like. On the other hand it's not necessary to run extra validations if you are instantiating from a database, because all the data in the DB is valid. You could introduce some private variable, like needsValidation, and set it to false in case you are instantiating from the DB via e.g. an internal constructor. Whether it's really worth the effort depends on your use case.

How to store/deal with data available to other classes in c#

I'm writing a CAD program. Let's say I have in input class, this class reads various data from a text file and creates lots of lists/dictionaries and .... These data need to be accessed by other methods in other classes to be modified. Now here is how I have done it so far:
I have one static class: Building.cs When I create/or load a project this class holds all the data like list of columns, beams, points, etc. All of these are stored as private fields. I can access these using the class's public methods like GetColumns or GetPoints ...
Now I also have non-static classes. They contain 2-3 public methods. and do some stuff on various parts of the building.
public static class Building
{
private static List<Column> columns;
private static List<Beams> beams;
private static List<Points> points;
public static List<Column> GetColumns()
{
return Columns;
}
}
public class ColumnsService()
{
private List<Columns> columns;
public GroupColumns(List<Columns> columns)
{
this.columns = columns;
}
public void Group()
{
// group columns
}
}
var columns = Building.GetColumns();
var columnsService = new ColumnsService(columns);
columnsService.Group();
I was wondering is this the way to go? How else can I store the data. The data needs to be accessible throughout the lifetime of the program to most of the classes. What are the best practices.
What, semantically, is a Building?
To me, the name implies that it's an instance of a structure. That, in the overall business domain, there can be many "buildings" and at any given moment one is interacting with one of them.
If that's the case, then it seems unintuitive to me to make it static. If there's more than one, it should be an instance model. It would contain attributes which describe it and operations which interact with it. The business domain being modeled should drive the structure of this object before any consideration is given to how other objects are going to interact with it.
So let's assume we make it an instance model:
public class Building
{
// attributes and operations
}
Then, as you ask, how do other objects interact with it?
Depends on the interactions.
Let's say an object needs to "render" a building in some way. Let's call it BuildingPrinter for lack of a better term. Clearly it needs a Building to "print". So it requires one for that operation:
public class BuildingPrinter
{
public void Print(Building building)
{
// implementation
}
}
Or perhaps you have an object which "wraps" a building in some way. Something which can't meaningfully exist without a building, regardless of the operations performed. I can't think of one for that particular business domain, so let's just call it a BuildingWidget. Since it needs a building to exist at all, it requires one:
public class BuildingWidget
{
private Building currentBuilding;
private BuildingWidget() { }
public BuildingWidget(Building building)
{
currentBuilding = building;
}
}
The point is, from the perspective of the models which construct the overall domain, if something is required then it must be supplied. The models shouldn't go out to some global data store, tightly coupling with that data store, to get what they need. This is called the Dependency Inversion Principle.
But where will the consuming code which orchestrates the interactions of these models get instances of a Building? There are a number of potential solutions to that.
Two common patterns would be to have a static factory or a repository. For example:
public class BuildingFactory
{
public static Building FetchBuilding(int buildingId)
{
// implementation
}
}
This factory might have a static cached building object. The building itself isn't static, but for performance reasons an instance of it is cached statically so that it's not constantly re-fetched from a backing data store (such as a database). You might also add methods to invalidate the cache and re-fetch, or encapsulate that logic into the factory itself (such as always re-fetch after 5 minutes or after 10 accesses or some other rule). (Behind the scenes, this factory might even use a repository, shown below, to re-fetch that instance. In which case, you guessed it, a BuildingRepository would be required on the BuildingFactory constructor.)
This factory object may also be responsible for creating a building based on some specifications, if for example you have reason to make the Building constructor private.
Or, to re-fetch from data, consider a repository:
public class BuildingRepository
{
public Building GetBuilding(int buildingId)
{
// fetch from database
}
public Building SaveBuilding(Building building)
{
// save to database, return updated version
}
}
Then other code throughout the domain, including the consuming code, can use these objects to get/save buildings. The factory is static, so that can be invoked anywhere. The repository is instance but doesn't need to be globally distinct, so that can be instantiated anywhere (or pulled form a dependency injection container).

C# DDD Populate Immutable Objects

I have a immutable Customer class in my domain assembly. It contains the following GET properties : id, firstname and lastname. I have a CustomerRepository class in my persistence assembly. In turn, this CustomerRepository class should populate and return a Customer object using a remote web-serivce.
My Customer class contains no setter properties and it contains a private constructor. The reason - I dont want the UI developer to get the wrong idea - He should not be able to create or change a Customer object.
My question: How do I get my CustomerRepository to populate my Customer object. Reflection? Or should I sacrifice my design and enable a public constructor for constructing the customer object?
I sympathize with the desire to reduce the surface of the API and not mislead callers, but I still recommend adding a public constructor. The fact that there are no setters and no public SaveCustomer method should make it clear enough that the customer is immutable.
If you really don't want a public constructor, consider whether you really need separate domain and persistence assemblies: there are good reasons to split related code into two assemblies, but it shouldn't be the default position and shouldn't replace namespaces as the primary way of organizing code (Patrick Smacchia has written a few great articles explaining why).
If you combine them into a single assembly, you can just make the constructor internal and be done with it. (As another respondent mentioned, InternalsVisibleTo is a viable alternative - but it's really just a hack: your classes and design goals are telling you these should be in a single assembly.)
You might want to declare an internal constructor, with your three properties as parameters. If your CustomerRepository does not live in the same assembly as your Customer class, then you can make your internals visible by using the following attribute:
[assembly: InternalsVisibleTo ("CustomerAssembly, PublicKey=...")]
in the Customer assembly.
Edit: By the way, I would not recommend using reflection if you need to create lots of objects, because doing so will be orders of magnitude slower than direct calls to constructors. If you really have to go that route, I'd recommend adding a static factory method which you can call through reflection in order to get an efficient allocator.
For instance:
class Customer
{
private Customer(...) { ... }
private static ICustomerFactory GetCustomerFactory()
{
return new CustomerFactory();
}
private class CustomerFactory : ICustomerFactory
{
Customer CreateCustomer(...) { return new Customer(...); }
}
}
public interface ICustomerFactory
{
Customer CreateCustomer(...);
}
Use reflection to call Customer.GetCustomerFactory and from then on, you'll have a fast and efficient way of creating your Customers.

Is there anything wrong with having a few private methods exposing IQueryable<T> and all public methods exposing IEnumerable<T>?

I'm wondering if there is a better way to approach this problem. The objective is to reuse code.
Let’s say that I have a Linq-To-SQL datacontext and I've written a "repository style" class that wraps up a lot of the methods I need and exposes IQueryables. (so far, no problem).
Now, I'm building a service layer to sit on top of this repository, many of the service methods will be 1<->1 with repository methods, but some will not. I think a code sample will illustrate this better than words.
public class ServiceLayer
{
MyClassDataContext context;
IMyRepository rpo;
public ServiceLayer(MyClassDataContext ctx)
{
context = ctx;
rpo = new MyRepository(context);
}
private IQueryable<MyClass> ReadAllMyClass()
{
// pretend there is some complex business logic here
// and maybe some filtering of the current users access to "all"
// that I don't want to repeat in all of the public methods that access
// MyClass objects.
return rpo.ReadAllMyClass();
}
public IEnumerable<MyClass> GetAllMyClass()
{
// call private IQueryable so we can do attional "in-database" processing
return this.ReadAllMyClass();
}
public IEnumerable<MyClass> GetActiveMyClass()
{
// call private IQueryable so we can do attional "in-database" processing
// in this case a .Where() clause
return this.ReadAllMyClass().Where(mc => mc.IsActive.Equals(true));
}
#region "Something my class MAY need to do in the future"
private IQueryable<MyOtherTable> ReadAllMyOtherTable()
{
// there could be additional constrains which define
// "all" for the current user
return context.MyOtherTable;
}
public IEnumerable<MyOtherTable> GetAllMyOtherTable()
{
return this.ReadAllMyOtherTable();
}
public IEnumerable<MyOtherTable> GetInactiveOtherTable()
{
return this.ReadAllMyOtherTable.Where(ot => ot.IsActive.Equals(false));
}
#endregion
}
This particular case is not the best illustration, since I could just call the repository directly in the GetActiveMyClass method, but let’s presume that my private IQueryable does some extra processing and business logic that I don't want to replicate in both of my public methods.
Is that a bad way to attack an issue like this? I don't see it being so complex that it really warrants building a third class to sit between the repository and the service class, but I'd like to get your thoughts.
For the sake of argument, lets presume two additional things.
This service is going to be exposed through WCF and that each of these public IEnumerable methods will be calling a .Select(m => m.ToViewModel()) on each returned collection which will convert it to a POCO for serialization.
The service will eventually need to expose some context.SomeOtherTable which wont be wrapped into the repository.
I think it's a good model since you can create basic IQueryable private functions that can be used by the functions you are exposing publicly. This way your public methods do not need to recreate a lot of the common functionality your IQueryable methods perform and they can be extended as needed and deferring the execution while still hiding that functionality publicly.
An example like how to get X out of some table which may take a lot of logic that you don't need in it's raw form. You then have that as a private method, as you do in your example, and then the public method adds the finalizing criteria or queries to generate a useable set of data which could differ from function to function. Why keep reinventing the wheel over and over... just create the basic design (which you IQueryable does) and drop on the tread pattern that is required as needed (your public IEnumerable does) :)
+1 for a good design IMO.

Make an object accessible to only one other object in the same assembly?

Each business object has a matching object that contains sql calls. I'd like to restrict these sql objects in a way where they can only be used by the matching business object. How can this be achieved?
Update
Greg brought up the point about testability. Since the SqlObjects will contain very business-process specific sql I don't want them reused in multiple buiness objects. (Basic CRUD operations are all code-generated) Is there a way to make the SqlObjects accessible to only one business object in the business assembly (like yshuditelu and Greg Beech showed) AND expose the SqlObjects to the unit testing assembly?
If this is the approach you want or need to take, you could make the sql objects private classes within the business object.
public class BusinessObject
{
private class SqlObject { }
}
Additionally, by making use of partial classes, you could separate this into separate files if desired.
//in one file
public partial class BusinessObject
{
//business object implementation
}
//in another file
public partial class BusinessObject
{
private class SqlObject { }
}
Joel makes a good point in a comment below "the SqlObject can still inherit from a common type, to that things like connection information can be shared across those "inner" classes." this is absolutely true, and potentially very beneficial.
In response to your edit, unit tests can only test public classes and functions (without using reflection in your tests). The only option I can think of that would do this is:
make one assembly per business/sql object pair
changing the private class SqlObject to internal class SqlObject
then use the [InternalsVisibleTo("UnitTestsAssembly")] for the project
Also, at this point you wouldn't have to keep the sql object as a nested class. Generally speaking, I think this would likely add more complexity than the value it adds, but I completely understand that every situation is different, and if your requirements/expectations are driving you this, I wish you well. Personally, I think I would go with making the SqlObjects public (or internal with internals visible to for unit testing), and accept the fact that that means the sql classes are exposed to all of the business classes.
The only way to do it is make the SQL object a private nested type, i.e.
public class BusinessObject
{
private class SqlObject
{
}
}
Whether this is a good idea from the point of view of testability is another matter entirely...
You are attmepting to implement what is a Friend Class in C++. As far as I know C# and VB.Net do not have anything equivalent. My only suggestion is to make the class you wish to restrict an internal class of the class that needs to access it.
You could also work with two assemblies (one for business objects and one for the related SQL objects) and use the internal modifier on each SQL class and use then [InternalsVisibleTo("BusinessObjectAssembly")] for the SQLAssembly.

Categories