I am working on application that has WCF REST API and below some DAL. Everything is written in C#.
All REST methods are GET, but many of them have generic string parameter (among other params) that I parse and map to a list object. It works well.
When it comes to mapping to Dto object I would like to use some design pattern to instantiate correct Dto based on mapped REST params. Not sure is it possible since I have that generic string parameter (param name will not be the same all the time) ?
Also, based on created Dto type I would like to choose appropriate DB method to call, command design pattern for this one, I guess?
Thanks for help,
I could explain more if needed.
I have developed same kind of application (WCF REST service).
I have created .net solution and added below project
BusinessLayer
DataAcessLayer
DataService (WCF Service)
EntityLayer
DataService:
public SnapshotData GetSnapshot(string symbol, int nocache)
{
SnapshotData objSnapshotData;
try
{
objSnapshotData = (new SnapshotBAL()).GetSanpshotData(symbol);
SerializeObject(objSnapshotData, localCacheKey);
return objSnapshotData;
}
catch (Exception ex)
{
return null;
}
}
BusinessLayer:
namespace BusinessLayer
{
public class SnapshotBAL
{
public Snapshot GetSanpshot(string symbol)
{
return (new SnaapshotDAL()).GetSanpshot(symbol);
}
}
}
EntiryLayer:
namespace EntityLayer
{
public class Snapshot
{
public DateTime time { get; set; }
public double price { get; set; }
}
}
DataAccessLayer:
namespace DataAccessLayer
{
public class SnaapshotDAL : PrototypeDB
{
public Snapshot GetSanpshot(string symbol)
{
AddParameter("o_snapshot");
AddParameter("i_symbol", symbol);
Snapshot objSanapshot = new Snapshot();
return ObjectHelper.FillObject<Snapshot>(typeof(Snapshot), GetReader("A_SM7_V1_P.GetSnapshotQuick"));
}
}
}
The key line in the question is this:
...design pattern to instantiate correct Dto based on mapped REST params
To me this sounds like you want to use the Factory Pattern.
Urgh. Yes I know, cargo cult programming etc, BUT(!), there are good reasons:
You want to intialise a class (the DAL) based upon some settings
You want those settings defined at the top level (REST mapping)
You want lower level code to be totally ignorant of the settings (right?) so that they can change arbitrarily without requiring system wide refactors.
Sure, you could always just pass an instance of the DAL down the stack but that isn't always possible and can get a bit scrappy.
Alternatively...
Consider creating a DAL implementation that can be made aware of the various switches and will delegate calls to the correct DAL implementation. This might actually be lighter weight than a straight up factory.
Related
I am making a Storage System Application. Each storage system contains up to 10 Warehouses capable of storing Stock Items.
I want to create a method for updating a Warehouse properties (Name, Description etc). There is a business rule that each Warehouse within a storage system must have a unique name, and im unsure which class should be responsible for this. Im trying to stick to the principle that each class should only be responsible for itself.
Here is a simple mock up of the code (C#)
public class StorageSystem
{
public List<Warehouse> Warehouses{Get;}
}
public class Warehouse
{
public string Name{Get; private Set;}
public int StorageSystemId{Get; Set;}
public StorageSystem Sotrage System{Get; Set;}
}
I think i should do the following,
Step1. Create a method in StorageSystem class.
public bool WarehouseNameAvailable(string name)
{
//Check List of Warehouses for the name
//if found return false
//else return true
}
Step2. Create a method in the Warehouse
public void UpdateWarehouseName(string name)
{
if(StorageSystem.WarehouseNameAvailable(name))
{
this.name = name;
}
else
{
//Throw Exception
{
}
Is this the "proper and correct" way to do this?
Is this the "proper and correct" way to do this?
This highly depends on your overall application architecture, imho. Ask 5 developers whether your solution is "proper and correct" and you will get 6 opinions.
To get to the point: When purely relating on DDD concepts, your solution seems at least possible. But to be honest, i've never come across an enterprise application of notable size that was able to project its business logic entirely in the domain model in a structured (!) and maintainable (!) way and did not need some kind of service layer upon it. I personally like this approach and would recommend pojecting this requirements in separate classes, that represent business/use cases:
public class RenameAction {
//Some Kind of DbSet, Database Connection, external service,...
//I'll go with an EF - DbSet<Warehouse> in this example
private readonly DbSet<Warehouse>_warehouses;
private readonly DbSet<StorageSystem> _storageSystem;
public void Execute(int storageSystemId, int warehouseId, string name) {
var storageSystem = _storageSystems.Single(system => system.Id == storageSystemId);
if (_storageSystem.Warehouses.Any(wh => wh.Name == name))
throw new BusinessLogicException("Warehouse names must be unique within storage systems!");
var warehouse = storageSystem.Warehouses.Single(wh => wh.Id == warehouseId);
warehouse.Name = name;
//Write back the updated warehouse to whereever, this won't work with an DbSet<Warehouse>.
_warehouses.Update(warehouse);
}
}
But again, this is just how I would deal with that.
Make T_WAREHOUSE.NAME unique (just assumed that your table/columns would have names like this) - database wise and handle the exception if a second entry gets written with the same name.
You could rise that error/exception up to user level too, to show users what went wrong: enter a different name please, "Super Dooper Warehouse" is already taken
Your questions text suggests that this will be a bigger project with many classes that interact with each other.
If you are not using a ORM, think about using one! It does a lot what you are trying to achive via custom methods loke your WarehouseNameAvailable workaround.
If you are using Entity Framework you can do this on your class properties via [Unique] attribute.
Without a doubt I know what the controllers and models are used for. However, I am able to write code that interacts with my db, for example adding users to a table, on either the controller or model. At what times should I write code in the controller vs. in model? Even though both work, what would be a more organized or practical way. Could you please post examples if the answer is ambiguous?Thx
For that, you should add a logic layer or logic classes. The controller should determine wants to do and can do, shuffle them in the right direction (logic layer), then determine what to show the user after the logic. Putting the logic in a separate layer will help keep your controllers lean and promote code reuse.
In the domain core, we only have models with properties. All logic is performed in a different layer, except for things like a property that returns fields concatenated in a format.
Code to access the database should be in service layer instead of keeping in Controller or Model.
Accessing Database Entities from Controller
Here is my answer for the above question, you can also read others answers why you should keep in separate layer.
namespace MyProject.Web.Controllers
{
public class MyController : Controller
{
private readonly IKittenService _kittenService ;
public MyController(IKittenService kittenService)
{
_kittenService = kittenService;
}
public ActionResult Kittens()
{
// var result = _kittenService.GetLatestKittens(10);
// Return something.
}
}
}
namespace MyProject.Domain.Kittens
{
public class Kitten
{
public string Name {get; set; }
public string Url {get; set; }
}
}
namespace MyProject.Services.KittenService
{
public interface IKittenService
{
IEnumerable<Kitten> GetLatestKittens(int fluffinessIndex=10);
}
}
namespace MyProject.Services.KittenService
{
public class KittenService : IKittenService
{
public IEnumerable<Kitten> GetLatestKittens(int fluffinessIndex=10)
{
using(var db = new KittenEntities())
{
return db.Kittens // this explicit query is here
.Where(kitten=>kitten.fluffiness > 10)
.Select(kitten=>new {
Name=kitten.name,
Url=kitten.imageUrl
}).Take(10);
}
}
}
}
ASP.NET MVC and MVC, in general, is a presentation layer pattern; thus your interaction with the database should be in a layer beyond the presentation layer, usually a data-access layer, but it could be a service layer or business layer as well.
Apparently my education has failed me, because I didn't realize that methods in C# cannot be serialized. (Good to know.)
I am trying to create a WCF service that returns a simple class I created. The problem is that this simple class contains methods that I want to expose, and the caller of my service won't have any access to them (assuming they won't have a .dll containing the class declaration).
public class Simple
{
public string Message { get; set; }
private const string _Hidden = "Underpants";
public string Hidden
{
get { return _Hidden; }
}
public string GetHidden()
{
return _Hidden;
}
}
I set up a WCF service (let's call it MyService) to return an instance of my Simple class. To my frustration, I'm only getting a partial build of my class back.
public void CallService()
{
using (var client = new MyService.Serviceclient())
{
Simple result = client.GetSimple();
string message = result.Message; // this works.
string hidden = result.Hidden; // this doesn't.
string fail = result.GetHidden(); // Underpants remains elusive.
}
}
Is there any type of workaround where I'm able to set up a property or method on my class that will be accessible to whomever calls my service? How does one handle constants or other methods that are set up in a class that only exists in a service?
Typically you would create three different projects.
1. Service project
2. Client project
3. Data project
The Data project contains only the data classes - no application code. The methods and constants in these data classes should be independent of the Service/Client projects.
The Data project is included as a reference in both the Service and Client projects so that serialization and deserialization happen against the same binary - and you get to retain your constants/methods/etc.
The downside here is that all your clients will either have to be .NET apps, or you will have to provide different data libraries for each platform you wish to support.
As far as I know the only things that can be returned in a WCF service are primitives or a class with public properties that have a get method on them. From a high level WCF exists to allow you to specify a contract between the client and the server that it in theory transportation agnostic (ie you can swap out an HTTP endpoint for a netTcp endpoint and the service will function the same way from a contractual level).
The question to answer then is what data are you trying to pass back in this service call. If it's an object called simple with the data points of Message and Hidden then I would advise creating a data class called Simple that has those values as properties:
[DataContract]
public class Simple
{
[DataMember]
public string Hidden { get; set; }
[DataMember]
public string Message { get; set; }
}
When the client receives the response back Message and Hidden will be populated with whatever you have set their values to on the server side.
The DataMember attribute can only be used on properties and fields. This means that a WCF response can only serialize these types.
If you really want to only use the const in your WCF contract You could convert it to a field and place the DataMember attribute on it:
public class Simple
{
[DataMember]
public string Message { get; set; }
[DataMember]
public const string Hidden = "Underpants";
}
To be able to do this the field must be accessible (public).
Add the DataMember attribute to your property. To do so, you must have both a get and a set defined.
[DataMember]
public string Hidden
{
get { return _Hidden; }
set { }
}
technically you could do
public class thingToSerialize{
public Func<ArgType1,ArgType2...,ReturnType> myFunction{get;set;}
}
and then assign it a lambda that takes the arguments and returns the return type
before serializing
I'm trying work out the best way to structure our API; we have Reviews which we've setup in a standard REST structure (list one, list all, create, update etc). Where it doesn't quite fit the examples is: each review can be linked to one or more other types e.g. Event, Location or Thing.
My thinking is the urls would be along the lines of:
/event/reviews/ (or the reverse of this e.g. /reviews/event/)
/location/reviews/
/thing/reviews/
The issue I can see however is the "GET" for each of these should return the parent object i.e. an Event.
So using ServiceStack, what's the best way to handle this scenario? Is it to create a custom service for each data request rather than abusing the out-of-the-box REST setup or have I missed something more fundamental?
Firstly "Best" solution is a fairly subjective term. I'll generally aim for DRY, re-usable, performant solutions that promotes the least effort, friction and chattiness, whilst others may define "Best" in how closely it follows the principles of REST. So you will get varied responses depending on what the goals are. I can only offer how I would approach it.
ServiceStack service implementations are de-coupled from their custom routes
One thing to keep in mind is how you define and design your services in ServiceStack are fairly de-coupled in how you expose them, since you can expose your services under any custom route. ServiceStack encourages a message-based design so you should give each operation a distinct message.
Use a logical / hierarchical Url structure
I'd use a logical Url structure that I aim to represent the identifier of a noun, which is hierarchically structured, i.e. the parent path categorizes your resource and gives it meaningful context. So in this case if you wanted to expose Events and reviews my inclination is to go with following url structure:
/events //all events
/events/1 //event #1
/events/1/reviews //event #1 reviews
Each of these resource identifiers can have any HTTP Verb applied to them
Implementation
For the implementation I generally follow a message-based design and group all related operations based on Response type and call context. For this I would do something like:
[Route("/events", "GET")]
[Route("/events/category/{Category}", "GET")] //*Optional top-level views
public class SearchEvents : IReturn<SearchEventsResponse>
{
//Optional resultset filters, e.g. ?Category=Tech&Query=servicestack
public string Category { get; set; }
public string Query { get; set; }
}
[Route("/events", "POST")]
public class CreateEvent : IReturn<Event>
{
public string Name { get; set; }
public DateTime StartDate { get; set; }
}
[Route("/events/{Id}", "GET")]
[Route("/events/code/{EventCode}", "GET")] //*Optional
public class GetEvent : IReturn<Event>
{
public int Id { get; set; }
public string EventCode { get; set; } //Alternative way to fetch an Event
}
[Route("/events/{Id}", "PUT")]
public class UpdateEvent : IReturn<Event>
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime StartDate { get; set; }
}
And follow a similar pattern for Event reviews
[Route("/events/{EventId}/reviews", "GET")]
public class GetEventReviews : IReturn<GetEventReviewsResponse>
{
public int EventId { get; set; }
}
[Route("/events/{EventId}/reviews/{Id}", "GET")]
public class GetEventReview : IReturn<EventReview>
{
public int EventId { get; set; }
public int Id { get; set; }
}
[Route("/events/{EventId}/reviews", "POST")]
public class CreateEventReview : IReturn<EventReview>
{
public int EventId { get; set; }
public string Comments { get; set; }
}
The implementation should be fairly straight forward based on these messages, which (depending on code-base size) I would organize in 2 EventsService and EventReviewsService classes. I should note that I use pluralization for Service Request DTO names myself to avoid clashing with data models of the same name.
Although I've separated UpdateEvent and CreateEvent here, I will sometimes will merge them into a single idempotent StoreEvent operation if the use-case permits.
Physical Project Structure
Ideally the root-level AppHost project should be kept lightweight and implementation-free. Although for small projects with only a few services it's ok for everything to be in a single project and to simply grow your architecture when and as needed.
For medium-to-large projects we recommend the physical structure below which for the purposes of this example we'll assume our Application is called EventMan.
The order of the projects also show its dependencies, e.g. the top-level EventMan project references all sub projects whilst the last EventMan.ServiceModel project references none:
- EventMan
AppHost.cs // ServiceStack ASP.NET Web or Console Host Project
- EventMan.ServiceInterface // Service implementations (akin to MVC Controllers)
EventsService.cs
EventsReviewsService.cs
- EventMan.Logic //For larger projs: pure C# logic, data models, etc
IGoogleCalendarGateway //E.g of a external dependency this project could use
- EventMan.ServiceModel //Service Request/Response DTOs and DTO types
Events.cs //SearchEvents, CreateEvent, GetEvent DTOs
EventReviews.cs //GetEventReviews, CreateEventReview
Types/
Event.cs //Event type
EventReview.cs //EventReview type
With the EventMan.ServiceModel DTO's kept in their own separate implementation and dependency-free dll, you're freely able to share this dll in any .NET client project as-is - which you can use with any of the generic C# Service Clients to provide an end-to-end typed API without any code-gen.
Update
This recommended project structure is now contained in all ServiceStackVS' VS.NET Templates.
The Simple Customer REST Example has a small self-contained, real-world example of creating a simple REST Service utilizing an RDBMS.
I'm new to DDD, and I'm trying to apply it in real life. There is no questions about such validation logic, as null check, empty strings check, etc - that goes directly to entity constructor/property. But where to put validation of some global rules like 'Unique user name'?
So, we have entity User
public class User : IAggregateRoot
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
// other data and behavior
}
And repository for users
public interface IUserRepository : IRepository<User>
{
User FindByName(string name);
}
Options are:
Inject repository to entity
Inject repository to factory
Create operation on domain service
???
And each option more detailed:
1 .Inject repository to entity
I can query repository in entities constructor/property. But I think that keeping reference to repository in entity is a bad smell.
public User(IUserRepository repository)
{
_repository = repository;
}
public string Name
{
get { return _name; }
set
{
if (_repository.FindByName(value) != null)
throw new UserAlreadyExistsException();
_name = value;
}
}
Update: We can use DI to hide dependency between User and IUserRepository via Specification object.
2. Inject repository to factory
I can put this verification logic in UserFactory. But what if we want to change name of already existing user?
3. Create operation on domain service
I can create domain service for creating and editing users. But someone can directly edit name of user without calling that service...
public class AdministrationService
{
private IUserRepository _userRepository;
public AdministrationService(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public void RenameUser(string oldName, string newName)
{
if (_userRepository.FindByName(newName) != null)
throw new UserAlreadyExistException();
User user = _userRepository.FindByName(oldName);
user.Name = newName;
_userRepository.Save(user);
}
}
4. ???
Where do you put global validation logic for entities?
Thanks!
Most of the times it is best to place these kind of rules in Specification objects.
You can place these Specifications in your domain packages, so anybody using your domain package has access to them. Using a specification, you can bundle your business rules with your entities, without creating difficult-to-read entities with undesired dependencies on services and repositories. If needed, you can inject dependencies on services or repositories into a specification.
Depending on the context, you can build different validators using the specification objects.
Main concern of entities should be keeping track of business state - that's enough of a responsibility and they shouldn't be concerned with validation.
Example
public class User
{
public string Id { get; set; }
public string Name { get; set; }
}
Two specifications:
public class IdNotEmptySpecification : ISpecification<User>
{
public bool IsSatisfiedBy(User subject)
{
return !string.IsNullOrEmpty(subject.Id);
}
}
public class NameNotTakenSpecification : ISpecification<User>
{
// omitted code to set service; better use DI
private Service.IUserNameService UserNameService { get; set; }
public bool IsSatisfiedBy(User subject)
{
return UserNameService.NameIsAvailable(subject.Name);
}
}
And a validator:
public class UserPersistenceValidator : IValidator<User>
{
private readonly IList<ISpecification<User>> Rules =
new List<ISpecification<User>>
{
new IdNotEmptySpecification(),
new NameNotEmptySpecification(),
new NameNotTakenSpecification()
// and more ... better use DI to fill this list
};
public bool IsValid(User entity)
{
return BrokenRules(entity).Count() == 0;
}
public IEnumerable<string> BrokenRules(User entity)
{
return Rules.Where(rule => !rule.IsSatisfiedBy(entity))
.Select(rule => GetMessageForBrokenRule(rule));
}
// ...
}
For completeness, the interfaces:
public interface IValidator<T>
{
bool IsValid(T entity);
IEnumerable<string> BrokenRules(T entity);
}
public interface ISpecification<T>
{
bool IsSatisfiedBy(T subject);
}
Notes
I think Vijay Patel's earlier answer is in the right direction, but I feel it's a bit off. He suggests that the user entity depends on the specification, where I belief that this should be the other way around. This way, you can let the specification depend on services, repositories and context in general, without making your entity depend on them through a specification dependency.
References
A related question with a good answer with example: Validation in a Domain Driven Design.
Eric Evans describes the use of the specification pattern for validation, selection and object construction in chapter 9, pp 145.
This article on the specification pattern with an application in .Net might be of interest to you.
I would not recommend disallowing to change properties in entity, if it's a user input.
For example, if validation did not pass, you can still use the instance to display it in user interface with validation results, allowing user to correct the error.
Jimmy Nilsson in his "Applying Domain-Driven Design and Patterns" recommends to validate for a particular operation, not just for persisting. While an entity could be successfully persisted, the real validation occurs when an entity is about to change it's state, for example 'Ordered' state changes to 'Purchased'.
While creating, the instance must be valid-for-saving, which involves checking for uniqueness. It's different from valid-for-ordering, where not only uniqueness must be checked, but also, for example, creditability of a client, and availability at the store.
So, validation logic should not be invoked on a property assignments, it should be invoked upon aggregate level operations, whether they are persistent or not.
Edit: Judging from the other answers, the correct name for such a 'domain service' is specification. I've updated my answer to reflect this, including a more detailed code sample.
I'd go with option 3; create a domain service specification which encapsulates the actual logic that performs the validation. For example, the specification initially calls a repository, but you could replace it with a web service call at a later stage. Having all that logic behind an abstract specification will keep the overall design more flexible.
To prevent someone from editing the name without validating it, make the specification a required aspect of editing the name. You can achieve this by changing the API of your entity to something like this:
public class User
{
public string Name { get; private set; }
public void SetName(string name, ISpecification<User, string> specification)
{
// Insert basic null validation here.
if (!specification.IsSatisfiedBy(this, name))
{
// Throw some validation exception.
}
this.Name = name;
}
}
public interface ISpecification<TType, TValue>
{
bool IsSatisfiedBy(TType obj, TValue value);
}
public class UniqueUserNameSpecification : ISpecification<User, string>
{
private IUserRepository repository;
public UniqueUserNameSpecification(IUserRepository repository)
{
this.repository = repository;
}
public bool IsSatisfiedBy(User obj, string value)
{
if (value == obj.Name)
{
return true;
}
// Use this.repository for further validation of the name.
}
}
Your calling code would look something like this:
var userRepository = IoC.Resolve<IUserRepository>();
var specification = new UniqueUserNameSpecification(userRepository);
user.SetName("John", specification);
And of course, you can mock ISpecification in your unit tests for easier testing.
I’m not an expert on DDD but I have asked myself the same questions and this is what I came up with:
Validation logic should normally go into the constructor/factory and setters. This way you guarantee that you always have valid domain objects. But if the validation involves database queries that impact your performance, an efficient implementation requires a different design.
(1) Injecting Entities: Injecting entities can be technical difficult and also makes managing application performance very hard due to the fragmentation of you database logic. Seemingly simple operations can now have an unexpectedly performance impact. It also makes it impossible to optimize your domain object for operations on groups of the same kind of entities, you no longer can write a single group query, and instead you always have individual queries for each entity.
(2) Injecting repository: You should not put any business logic in repositories. Keep repositories simple and focused. They should act as if they were collections and only contain logic for adding, removing and finding objects (some even spinoff the find methods to other objects).
(3) Domain service This seems the most logical place to handle the validation that requires database querying. A good implementation would make the constructor/factory and setters involved package private, so that the entities can only be created / modified with the domain service.
I would use a Specification to encapsulate the rule. You can then call when the UserName property is updated (or from anywhere else that might need it):
public class UniqueUserNameSpecification : ISpecification
{
public bool IsSatisifiedBy(User user)
{
// Check if the username is unique here
}
}
public class User
{
string _Name;
UniqueUserNameSpecification _UniqueUserNameSpecification; // You decide how this is injected
public string Name
{
get { return _Name; }
set
{
if (_UniqueUserNameSpecification.IsSatisifiedBy(this))
{
_Name = value;
}
else
{
// Execute your custom warning here
}
}
}
}
It won't matter if another developer tries to modify User.Name directly, because the rule will always execute.
Find out more here
In my CQRS Framework, every Command Handler class also contains a ValidateCommand method, which then calls the appropriate business/validation logic in the Domain (mostly implemented as Entity methods or Entity static methods).
So the caller would do like so:
if (cmdService.ValidateCommand(myCommand) == ValidationResult.OK)
{
// Now we can assume there will be no business reason to reject
// the command
cmdService.ExecuteCommand(myCommand); // Async
}
Every specialized Command Handler contains the wrapper logic, for instance:
public ValidationResult ValidateCommand(MakeCustomerGold command)
{
var result = new ValidationResult();
if (Customer.CanMakeGold(command.CustomerId))
{
// "OK" logic here
} else {
// "Not OK" logic here
}
}
The ExecuteCommand method of the command handler will then call the ValidateCommand() again, so even if the client didn't bother, nothing will happen in the Domain that is not supposed to.
in short you have 4 options:
IsValid method: transition an entity to a state (potentially invalid) and ask it to validate itself.
Validation in application services.
TryExecute pattern.
Execute / CanExecute pattern.
read more here
Create a method, for example, called IsUserNameValid() and make that accessible from everywhere. I would put it in the user service myself. Doing this will not limit you when future changes arise. It keeps the validation code in one place (implementation), and other code that depends on it will not have to change if the validation changes You may find that you need to call this from multiple places later on, such as the ui for visual indication without having to resort to exception handling. The service layer for correct operations, and the repository (cache, db, etc.) layer to ensure that stored items are valid.
I like option 3. Simplest implementation could look so:
public interface IUser
{
string Name { get; }
bool IsNew { get; }
}
public class User : IUser
{
public string Name { get; private set; }
public bool IsNew { get; private set; }
}
public class UserService : IUserService
{
public void ValidateUser(IUser user)
{
var repository = RepositoryFactory.GetUserRepository(); // use IoC if needed
if (user.IsNew && repository.UserExists(user.Name))
throw new ValidationException("Username already exists");
}
}
Create domain service
Or I can create domain service for
creating and editing users. But
someone can directly edit name of user
without calling that service...
If you properly designed your entities this should not be an issue.