I'm studying SOLID principles and have a question about dependency management in relation to interfaces.
An example from the book I'm reading (Adaptive Code via C# by Gary McLean Hall) shows a TradeProcessor class that will get the trade data, process it, and store it in the database. The trade data is modeled by a class called TradeRecord. A TradeParser class will handle converting the trade data that is received into a TradeRecord instance(s). The TradeProcessor class only references an ITradeParser interface so that it is not dependent on the TradeParser implementation.
The author has the Parse method (in the ITradeParser interface) return an IEnumerable<TradeRecord> collection that holds the processed trade data. Doesn't that mean that ITradeParser is now dependent on the TradeRecord class?
Shouldn't the author have done something like make an ITradeRecord interface and have Parse return a collection of ITradeRecord instances? Or am I missing something important?
Here's the code (the implementation of TradeRecord is irrelevant so it is omitted):
TradeProcessor.cs
public class TradeProcessor
{
private readonly ITradeParser tradeParser;
public TradeProcessor(ITradeParser tradeParser)
{
this.tradeParser = tradeParser;
}
public void ProcessTrades()
{
IEnumerable<string> tradeData = "Simulated trade data..."
var trades = tradeParser.Parse(tradeData);
// Do something with the parsed data...
}
}
ITradeParser.cs
public interface ITradeParser
{
IEnumerable<TradeRecord> Parse(IEnumerable<string> tradeData);
}
This is a good question that goes into the tradeoff between purity and practicality.
Yes, by pure principal, you can say that ITradeParser.Parse should return a collection of ITraceRecord interfaces. After all, why tie yourself to a specific implementation?
However, you can take this further. Should you accept an IEnumerable<string>? Or should you have some sort of ITextContainer? I32bitNumeric instead of int? This is reductio ad absurdum, of course, but it shows that we always, at some point, reach a point where we're working on something, a concrete object (number, string, TraceRecord, whatever), not an abstraction.
This also brings up the point of why we use interfaces in the first place, which is to define contracts for logic and functionality. An ITradeProcessor is a contract for an unknown implementation that can be replaced or updated. A TradeRecord isn't a contract for implementation, it is the implementation. If it's a DTO object, which it seems to be, there would be no difference between the interface and the implementation, which means there's no real purpose in defining this contract - it's implied in the concrete class.
The author has the Parse method (in the ITradeParser interface) return an IEnumerable collection that holds the processed trade data.
Doesn't that mean that ITradeParser is now dependent on the TradeRecord class?
Yes, ITradeParser is now tightly coupled with TradeRecord. Given the more academic approach of this question, I can see where you are coming from. But what is TradeRecord? A record, by definition, is generally a simple, non-intelligent piece of data (sometimes called POCO, DTO, or Model).
At some point, the potential gain of abstraction is less valuable than the complexities it causes. This approach is pretty common in practice - Models (as I refer to them) are sealed types that flow through the layers of an application. Layers that act upon the models are abstracted to interfaces, so that each layer may be mocked and tested separately.
For example, a client application may have a View, ViewModel, and Repository layer. Each layer knows how to work with the concrete record type. But the ViewModel could be wired up to work with a mocked IRepository, which builds up the concrete types with hardcoded, mocked data. There's no benefit to an abstracted IModel at this point - it just has straight data.
Related
I'm working on a domain model writing my software all DDD and stuff doing a great job, when I suddenly bump into the same problem I have been facing over and over again and now it's time to share some insights. The root of the problem lies in the uniqueness of data.
For example, let's say we're writing this awesome domain model for a user. Obviously the username is unique and just to be as flexible as possible we want the user to be able to change his name, so I implemented the following method:
public void SetUsername(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
throw new UserException(UserErrorCode.UsernameNullOrEmpty,
"The username cannot be null or empty");
}
if (!Regex.IsMatch(value, RegularExpressions.Username))
{
throw new UserException(UserErrorCode.InvalidUsername,
"The username {value} does not meet the required ");
}
if (!Equals(Username, value))
{
Username = value;
SetState(TrackingState.Modified);
}
}
Again, this is all fine and fancy, but this function lacks the ability to check if the username is unique or not. So writing all these nice articles about DDD, this would be a nice use-case for a Domain Service. Ideally, I would inject that service using dependency injection but this ruins the constructor of my domain model. Alternatively, I can demand an instance of a domain service as a function argument like so: public void SetUsername(string value, IUsersDomainService service) and to be honest I don't see any solid alternatives.
Who has faced this problem and maybe came up with a nice rock-solid solution?
I agree with #TomTom. But as most times with software decisions, it depends, there is almost always a tradeoff. As a rule of thumb, you gain more by not injecting a domain service into an entity. This is a common question when one is starting with DDD and CQRS+ES. And has been thoroughly discussed in the CQRS mailing list here
However, there are some cases where the approach you suggested (known as method injection) might be beneficial it depends on the scenario. I’ll try and drive some analysis points next.
Consider the case where you want to make some validation before creating an entity. Let's think of a hypothetical and way oversimplified international banking context, with the following entity:
public class BankNote
{
private BankNote() {}
public static FromCurrency(
Currency currency,
ISupportedCurrencyService currencyService)
{
currencyService.IsAvailable(currency);
}
}
I am using the factory method pattern FromCurrency inside your entity to abstract the entity creation process and add some validation so that the entity is always created in the correct state.
Since the supported currencies might change overtime, and the logic of which currencies are supported is a different responsibility than the bank note issuing logic, injecting the ISupportedCurrencyService in the factory method gives us the following benefits:
By the way, the method dependency injection for domain services is suggested in the book: Hands-On Domain-Driven Design with .NET Core
By Alexey Zimarev. Chapter 5 "Implementing the Model" page 120
Pros
The BankNote is always created with a supported Currency, even if the currencies supported change overtime.
Since we are depending on an interface instead of a concrete implementation, we can easily swap and change the implementation without changing the entity.
The service is never stored as an instance variable of the class, so no risk of depending on it more than we need.
Cons
If we keep going this way we might add a lot of dependencies injected into the entity and it will become hard to maintain overtime.
We still are adding a loosely coupled dependency to the entity and hence the entity now needs to know about that interface. We are violating the Single Responsibility Principle, and now you would need to mock the ISupportedCurrencyService to test the factory method.
We can’t instantiate the entity without depending on a service implemented externally from the domain. This can cause serious memory leak and performance issues depending on the scenario.
Another approach
You can avoid all the cons if you call the service before trying to instantiate the entity. Say having a different class for the factory instead of a factory method, and make that separate factory use the ISupportedCurrencyService and only then call the entity constructor.
public class BankNoteFactory
{
private readonly ISupportedCurrencyService _currencyService;
private BankNoteFactory(
ISupportedCurrencyService currencyService)
=> _currencyService = currencyService;
public BankNote FromCurrency(
Currency currency)
{
if(_currencyService.IsAvailable(currency))
return new BanckNote(currency);
// To call the constructor here you would also need
// to change the constructor visibility to internal.
}
}
Using this approach you would end with one extra class and an entity that could be instantiated with unsupported currencies, but with better SRP compliance.
I'm currently wondering what's the suggested way to separate plain model classes (for e.g. using them in Entity Framework, Web API, MVC, WCF...) from their application logic parts (server side tasks, threads etc.) utilizing the DRY principe.
Consider this pseduo example:
public class HorseOfDoom {
private Thread _hungerThread;
private Laser _headMountedLaser = new Laser();
public int Age { get; set; }
public string Name { get; set; }
public int Health { get; set; }
public int HungerLevel { get; set; }
public HorseOfDoom() {
_hungerThread.Start();
}
public void PewPew() {
_headMountedLaser.PewPew();
}
}
In this class we have both - model properties that describe the model (age, name,..), but also a thread and methods. I can use this class in Entity Framework, WCF and so on.. but what if I want to use the model in a ASP.NET MVC client application without exposing the methods, threads? Do I have to write the same class again? Do I need managers, adapters and facades? Could I use the buddy class pattern?
Use a model fit for the context. DRY is not about repeating lines of code, it's about repeating behaviour. Your view model can have the same properties (copy paste ftw) as the business model, minus the methods. You can use Automapper to map one to the other. Chances are your view model will have more than only those properties, including validation attributes or other data neede by the view in a certain format.
A model to rule'm all is not good on the long term. Clean models will alow you to focus better on the context and avoid coupling to other contexts, which might use a very similar or identical model. Things change in time and it's easier to work with a specific model from the beginning even if that involves copy paste and it seems that you're repeating yourself.
I understand that a combination as you show it in your sample is not really desirable - my main point of critique would be the thread that already implies a very concrete way on how the object should behave. The probability is high that the thread contained in the class itself will make it harder to use the class in some environments. From my point of view, the platform that integrates the class should be able to choose how to orchestrate the actions of the class - of course the class can make some restrictions like "not to be used in a separate thread as the class is not implemented in a thread-safe way".
As for the point of whether to combine properties and methods in a class: I don't think that there is a clear and always valid answer. It depends very much on how big the architecture of your application is and whether you are willing to pay the price for the separation in terms of complexity and overhead.
The concept of combining properties and methods in a single class is usually referred to as "Domain Model". It is a very natural approach to design complex business logic.
If you have an architecture that sets out to separate the layers very well, you'd have a Domain Model in the business logic that implements the business rules. These classes combine properties and methods, but these classes are mapped to simpler versions (e.g. DTOs) that only transport the data to other layers. This way, you also de-couple a service interface from the domain model and change them with minimal influences on the other layers. For instance, if you have complex classes in the domain model and you want to present only a part of this information in a web interface or through a service layer, you could create one or more DTO classes that contain exactly the data that is needed. Changes to the domain model will not necessarily affect clients so that you gain freedom in this respect.
In a smaller architecture however, you might not need to separate the layers with DTOs if you can live with the consequences.
As for the mentioned example of WCF, you have separate service and data contracts that you typically implement in different classes. If you have additional methods in a class that serves as a data contract those methods will not be part of the data contract. You'd have to explicitly make the methods that you want to publish part of a service contract. If you don't share the classes with a service client (e.g. through a class library), the client will not even know that these methods exist.
I have a database that contains "widgets", let's say. Widgets have properties like Length and Width, for example. The original lower-level API for creating wdigets is a mess, so I'm writing a higher-level set of functions to make things easier for callers. The database is strange, and I don't have good control over the timing of the creation of a widget object. Specifically, it can't be created until the later stages of processing, after certain other things have happened first. But I'd like my callers to think that a widget object has been created at an earlier stage, so that they can get/set its properties from the outset.
So, I implemented a "ProxyWidget" object that my callers can play with. It has private fields like private_Length and private_Width that can store the desired values. Then, it also has public properties Length and Width, that my callers can access. If the caller tells me to set the value of the Width property, the logic is:
If the corresponding widget object already exists in the database, then set
its Width property
If not, store the given width value in the private_Width field for later use.
At some later stage, when I'm sure that the widget object has been created in the database, I copy all the values: copy from private_Width to the database Width field, and so on (one field/property at a time, unfortunately).
This works OK for one type of widget. But I have about 50 types, each with about 20 different fields/properties, and this leads to an unmaintainable mess. I'm wondering if there is a smarter approach. Perhaps I could use reflection to create the "proxy" objects and copy field/property data in a generic way, rather than writing reams of repetitive code? Factor out common code somehow? Can I learn anything from "data binding" patterns? I'm a mathematician, not a programmer, and I have an uneasy feeling that my current approach is just plain dumb. My code is in C#.
First, in my experience, manually coding a data access layer can feel like a lot of repetitive work (putting an ORM in place, such as NHibernate or Entity Framework, might somewhat alleviate this issue), and updating a legacy data access layer is awful work, especially when it consists of many parts.
Some things are unclear in your question, but I suppose it is still possible to give a high-level answer. These are meant to give you some ideas:
You can build ProxyWidget either as an alternative implementation for Widget (or whatever the widget class from the existing low-level API is called), or you can implement it "on top of", or as a "wrapper around", Widget. This is the Adapter design pattern.
public sealed class ExistingTerribleWidget { … }
public sealed class ShinyWidget // this is the wrapper that sits on top of the above
{
public ShinyWidget(ExistingTerribleWidget underlying) { … }
private ExistingTerribleWidget underlying;
… // perform all real work by delegating to `underlying` as appropriate
}
I would recommend that (at least while there is still code using the existing low-level API) you use this pattern instead of creating a completely separate Widget implementation, because if ever there is a database schema change, you will have to update two different APIs. If you build your new EasyWidget class as a wrapper on top of the existing API, it could remain unchanged and only the underlying implementation would have to be updated.
You describe ProxyWidget having two functions (1) Allow modifications to an already persisted widget; and (2) Buffer for a new widget, which will be added to the database later.
You could perhaps simplify your design if you have one common base type and two sub-classes: One for new widgets that haven't been persisted yet, and one for already persisted widgets. The latter subtype possibly has an additional database ID property so that the existing widget can be identified, loaded, modified, and updated in the database:
interface IWidget { /* define all the properties required for a widget */ }
interface IWidgetTemplate : IWidget
{
IPersistedWidget Create();
bool TryLoadFrom(IWidgetRepository repository, out IPersistedWidget matching);
}
interface IPersistedWidget : IWidget
{
Guid Id { get; }
void SaveChanges();
}
This is one example for the Builder design pattern.
If you need to write similar code for many classes (for example, your 50+ database object types) you could consider using T4 text templates. This just makes writing code less repetitive; but you will still have to define your 50+ objects somewhere.
I'm trying to wrap my head around Domain Driven Development. I want to make sure I have a good foundation and understanding of it, so it would be great if recommendations to use AutoMapper or similar are avoided here. My architecture currently involves the following:
The WCF service is responsible for persistence (using Entity Framework) and server-side validation. It converts POCO's to DTO's, and DTO's are transferred to the client.
The Client, receives DTO's and converts them to POCO's. The class that converts POCO's and DTO's is shared between the service and the client.
The POCO's implement IValidatableObject and INotifyPropertyChanged and are used by both the server and the client, but they are not used for data transfer. The DTO's are, which are just property bags containing no behavior.
(1) Question #1. Is this architecture appropriate for a Domain Driven Design.
(2) Question #2. Is it appropriate for POCO's to contain navigation properties? It really feels wrong for POCO's to contain navigation properties in a DDD architecture to me, because it doesn't make sense to me to have a navigation property that may or may not be serialized. It would make more sense to me to have a specialized DTO.
For example, here is a POCO/DTO looks like in my architecture.
// Enforces consistency between a POCO and DTO
public interface IExample
{
Int32 Id { get; set; }
String Name { get; set; }
}
// POCO
public class Example : IExample, INotifyPropertyChanged, IValidatableObject
{
private int id;
private string name;
public Int32 Id {
get { return this.id; }
set {
this.id = value;
OnPropertyChanged("Id");
}
}
public String Name {
get { return this.name; }
set {
this.name = value;
OnPropertyChanged("Name ");
}
}
public ICollection<Example2> ChildExamples {
get { ... }
set { ... }
}
// INotifyPropertyChanged Members
// IValidatableObject Members
}
// DTO
public class ExampleInfo : IExample
{
public Int32 Id { get; set; }
public String Name { get; set; }
public ICollection<Example2Info> ChildExamples { get; set; }
}
It doesn't seem right though, because you may not always need the navigation property, and having an empty (null) object (or collection) seems very wrong in an object-oriented architecture. You also have to deal with serializing and converting deep object hierarchies at times, which is not trivial. It would make more sense for a specialized DTO so there isn't a problem with the constant possibility of empty navigation properties that may or may not need serialized or populated.
public class ComplexInfo
{
public Example ExampleInfo { get; set; }
public ICollection<Example2Info> ChildExamples { get; set; }
}
How are these situations handled in real-world enterprise DDD style architectures and what other advice can be given here?
I agree with Jehof about sending the DTO's to your client and keeping the domain model clean on the server side under your WCF.
With respect to navigation properties, one point Eric Evans emphasizes in Domain Driven Design is to respect invariants. So, in your example above ask yourself if Id and Name are really going to change in the lifetime of the object, or are they invariants? A lot of DDD-style developers would not even put a setter on those properties. Instead build the object's invariant state through a constructor. If Name can change, you probably want a method called Rename(string newName), because there's probably some kind of business rules you'd want to put there anyway.
A red flag in your layers above is that you have your whole object model in the DAL. What you call your assemblies really isn't a big deal but I think it points to your tendency to keep thinking of the application from a data perspective. The point of DDD is to think of your object model in terms of logic and behavior, not data and structure. I (and most other DDD developers, I think) think of the data access layer as Repository classes which return Aggregate Roots. The repositories are responsible for returning your hydrated poco/entity objects from the DAL(repository) to the business layer (and above, such as an application/service layer class or your WCF in your above example). In your case of using EF, you'd have the repositories wrap your DataContext calls and return the entity objects.
I could go on and on, because your question is really targeting the basic fundamentals of DDD, of which there are several. I would recommend 1) Read Eric Evans book, "Domain Driven Design". 2) Keep in mind that DDD targets complex business software. If you're trying to apply it to a simple CRUD application which really is just UI forms and data binding to DB tables, its hard to see a DDD approach take shape, because the problems it addresses just aren't there. So keep that in perspective.
Is this architecture appropriate for a Domain Driven Design?
Not entirely. Take a look at hexagonal architecture for a description of a more modern architectural style which fits nicely with DDD. Within hexagonal, your domain is at the core and various components "attach" to it. For example, a WCF service would be considered an adapter in a hexagonal architecture because it adapts your domain to a communication technology such as TCP or HTTP. Typically, you would have an application service which establishes a facade over your domain and effectively represents use cases. This application service can be referenced by a WCF service to expose functionality over HTTP. Unfortunately, the "service" terminology can be a bit conflating.
Is it appropriate for POCO's to contain navigation properties?
It is appropriate, but the right answer is that it depends. One of the issues with navigational properties that you state is that they may or may not be serialized for a specific DTO. This is telling me that you are talking about queries. Some queries need only a subset of attributes on an aggregate/entity (POCO) and thus the corresponding DTO only has those required properties. It seems wasteful to retrieve an entire entity together with navigational properties. To address this issue you can employ lazy loading. A more salable approach however, is to use read-models for queries. Also, as stated by others, an entity/aggregate certainly can and should contain navigational properties if they are a reflection of the domain. How these "navigational" properties are implemented can vary. Sometimes it can be better to split an aggregate into multiple aggregates. Take a look at Effective Aggregate Design by Vaughn Vernon.
As pointed out by Jehof, you should try to have clients of the WCF service only depend on the contract of that service itself, not on the domain entities (POCOs) that the service encapsulates. Typically, POCOs should not implement INotifyPropertyChanged and IValidatableObject because those interfaces support UI concerns and should be handled by the DTOs or ViewModels.
Domain Driven Design isn't about POCO's or DTO's. It's about Entities, Aggregate Roots, Value Objects. About rich domain objects that can encapsulate behavior in addition to data.
Is it appropriate for POCO's to contain navigation properties ?
It's not clear to me what the POCOs are for in your scenario, but if they are your domain entities, then they can and should certainly contain navigation properties. Actually, using the navigation properties of an Aggregate Root (a special kind of domain entity) is often the only way for external objects to access entities enclosed in that Aggregate. Navigation through association properties is a key concept in DDD.
Also, the recommended architecture in DDD looks more or less like :
Presentation Layer (UI)
Application layer
Domain Layer
Infrastructure layer (includes persistence/DAL)
The key here is the Single Responsibility Principle. You don't want a service that does persistence, server-side validation and DTO mapping at the same time. You need decoupling. You need a clear distribution of responsibilities among your layers so that they are more easily maintainable, extensible and portable.
Another suggestion: think very hard whether to share the mapping code (and by implication the classes they are mapped to) between the client the server.
There is nothing wrong with sharing code, but be careful you are not mixing client concerns and server concerns. It may start with small compromises "I need this property only on the client, but everything else is the same", but you might end up with flags to tell the class whether to use client or server behavior and other nastiness.
Having separate implementations of the POCO's may seem as code duplication at first, but it frees you to have an implementation fitted to the task.
That's why using Automapper and the like makes sense, it lowers the barrier of writing the mapping code.
Another reason to do this (which has been also mentioned) is that the DTO's should be a way to implement a communication API, and not the API itself: i.e. the DTO's are there for WCF to implement a SOAP API (or REST or whatever), but the client should be free to implement the communication layer using only the API specification, without any hidden logic in the mapping code.
This also ensures your API remains language agnostic. You might want to provide client libraries (in any of several appropriate languages) to ease the interaction with your API, but these should not be a requirement.
I am working on a project where I am wrestling with trying to move from one persistence pattern to another.
I've looked in Patterns of Enterprise Application Architecture, Design Patterns, and here at this MSDN article for help. Our current pattern is the Active Record pattern described in the MSDN article. As a first step in moving to a more modular code base we are trying to break out some of our business objects (aka tables) into multiple interfaces.
So for example, let's say I have a store application something like this:
public interface IContactInfo
{
...
}
public interface IBillingContactInfo: IContactInfo
{
...
}
public interface IShippingContactInfo: IContactInfo
{
...
}
public class Customer: IBillingContactInfo, IShippingContactInfo
{
#region IBillingContactInfo Implementation
...
#endregion
#region IShippingContactInfo Implementation
...
#endregion
public void Load(int customerID);
public void Save();
}
The Customer class represents a row in our Customer Table. Even though the Customer class is one row it actually implements two different interfaces: IBillingContactInfo, IShippingContactInfo.
Historically we didn't have those two interfaces we simply passed around the entire Customer object everywhere and made whatever changes we wanted to it and then saved it.
Here is where the problem comes in. Now that we have those two interfaces we may have a control that takes an IContactInfo, displays it to the user, and allows the user to correct it if it is wrong. Currently our IContactInfo interface doesn't implement any Save() to allow changes to it to persist.
Any suggestions on good design patterns to get around this limitation without a complete switch to other well known solutions? I don't really want to go through and add a Save() method to all my interfaces but it may be what I end up needing to do.
How many different derivatives of IContactInfo do you plan to have?
Maybe I'm missing the point, but I think you would do better with a class called ContactInfo with a BillTo and a ShipTo instance in each Customer. Since your IShippingContactInfo and IBillingContactInfo interfaces inherit from the same IContactInfo interface, your Customer class will satisfy both IContactInfo base interfaces with one set of fields. That would be a problem.
It's better to make those separate instances. Then, saving your Customer is much more straight-forward.
Are you planning on serialization for persistence or saving to a database or something else?
Using a concrete type for Customer and ContactInfo would definitely cover the first two.
(A flat file would work for your original setup, but I hope you aren't planning on that.)
I think it all comes down to how many derivatives of IContactInfo you expect to have. There is nothing wrong with a bit more topography in your graph. If that means one record with multiple portions (your example), or if that is a one-to-many relationship (my example), or if it is a many-to-many that lists the type (ShipTo, BillTo, etc.) in the join table. The many-to-many definitely reduces the relationships between Customer and the various ContactInfo types, but it creates overhead in application development for the scenarios when you want concrete relationships.
You can easily add a Save() method constraint to the inherited interfaces by simply having IContactInfo implement an IPersistable interface, which mandates the Save() method. So then anything that has IContactInfo also has IPersistable, and therefore must have Save(). You can also do this with ILoadable and Load(int ID) - or, with more semantic correctness, IRetrievable and Retrieve(int ID).
This completely depends on how you're using your ContactInfo objects though. If this doesn't make sense with relation to your usage please leave a comment/update your question and I'll revisit my answer.