Sorry for this point being all over the place here...but I feel like a dog chasing my tail and I'm all confused at this point.
I'm trying to see the cleanest way of developing a 3 tiered solution (IL, BL, DL) where the DL is using an ORM to abstract access to a DB.
Everywhere I've seen, people use either LinqToSQL or LLBLGen Pro to generate objects which represent the DB Tables, and refer to those classes in all 3 layers.
Seems like 40 years of coding patterns have been ignored -- or a paradigm shift has happened, and I missed the explanaition part as to why its perfectly ok to do so.
Yet, it appears that there is still some basis to desiring being data storage mechanism agnostic -- look what just happened to LinqToSQL: a lot of code was written against it -- only for MS
to drop it... So I would like to isolate the ORM part as best I can, just don't know how.
So, going back to absolute basics, here are the basic parts that I wish to have assembled in a very very clean way:
The Assemblies I'm starting from:
UL.dll
BL.dll
DL.dll
The main classes:
A Message class that has a property exposing collection (called MessageAddresses) of MessageAddress objects:
class Message
{
public MessageAddress From {get;}
public MessageAddresses To {get;}
}
The functions per layer:
The BL exposes a Method to the UI called GetMessage (Guid id) which returns an instance of Message.
The BL in turn wraps the DL.
The DL has a ProviderFactory which wraps a Provider instance.
The DL.ProviderFactory exposes (possibly...part of my questions) two static methods called
GetMessage(Guid id), and
SaveMessage(Message message)
The ultimate goal would be to be able to swap out a provider that was written for Linq2SQL for one for LLBLGen Pro, or another provider that is not working against an ORM (eg VistaDB).
Design Goals:
I would like layer separation.
I would like each layer to only have dependency on layer below it, rather than above it.
I would like ORM generated classes to be in DL layer only.
I would like UL to share Message class with BL.
Therefore, does this mean that:
a) Message is defined in BL
b) The Db/Orm/Manual representation of the DB Table ('DbMessageRecord', or 'MessageEntity', or whatever else ORM calls it) is defined in DL.
c) BL has dependency on DL
d) Before calling DL methods, that do not have ref or know about BL, the BL has to convert them BL entities (eg: DbMessageRecord)?
UL:
Main()
{
id = 1;
Message m = BL.GetMessage(id);
Console.Write (string.Format("{0} to {1} recipients...", m.From, m.To.Count));
}
BL:
static class MessageService
{
public static Message GetMessage(id)
{
DbMessageRecord message = DLManager.GetMessage(id);
DbMessageAddressRecord[] messageAddresses = DLManager.GetMessageAddresses(id);
return MapMessage(message,
}
protected static Message MapMessage(DbMessageRecord dbMessage. DbMessageAddressRecord[] dbAddresses)
{
Message m = new Message(dbMessage.From);
foreach(DbMessageAddressRecord dbAddressRecord in dbAddresses){
m.To.Add(new MessageAddress (dbAddressRecord.Name, dbAddressRecord.Address);
}
}
DL:
static class MessageManager
{
public static DbMessageRecord GetMessage(id);
public static DbMessageAddressRecord GetMessageAddresses(id);
}
Questions:
a) Obviously this is a lot of work sooner or later.
b) More bugs
c) Slower
d) Since BL now dependency on DL, and is referencing classes in DL (eg DbMessageRecord), it seems that since these are defined by ORM, that you can't rip out one Provider, and replace it with another, ...which makes the whole exercise pointless...might as well use the classes of the ORM all through the BL.
e) Or ...another assembly is needed in between the BL and DL and another mapping is required in order to leave BL independent of underlying DL classes.
Wish I could ask the questions clearer...but I'm really just lost at this point. Any help would be greatly appreciated.
that is a little all over the place and reminds me of my first forays into orm and DDD.
I personally use core domain objects, messaging objects, message handlers and repositories.
So my UI sends a message to a handler which in turn hydrates my objects via repositories and executes the business logic in that domain object. I use NHibernate to for my data access and FluentNHibernate for typed binding rather than loosy goosey .hbm config.
So the messaging is all that is shared between my UI and my handlers and all BL is on the domain.
I know i might have opened myself up for punishment for my explanation, if its not clear i will defend later.
Personally i am not a big fan of code generated objects.
I have to keep adding onto this answer.
Try to think of your messaging as a command rather than as a data entity representing your db. I'll give u an example of one of my simple classes and an infrastructure decision that worked very well for me that i cant take credit for:
[Serializable]
public class AddMediaCategoryRequest : IRequest<AddMediaCategoryResponse>
{
private readonly Guid _parentCategory;
private readonly string _label;
private readonly string _description;
public AddMediaCategoryRequest(Guid parentCategory, string label, string description)
{
_parentCategory = parentCategory;
_description = description;
_label = label;
}
public string Description
{
get { return _description; }
}
public string Label
{
get { return _label; }
}
public Guid ParentCategory
{
get { return _parentCategory; }
}
}
[Serializable]
public class AddMediaCategoryResponse : Response
{
public Guid ID;
}
public interface IRequest<T> : IRequest where T : Response, new() {}
[Serializable]
public class Response
{
protected bool _success;
private string _failureMessage = "This is the default error message. If a failure has been reported, it should have overwritten this message.";
private Exception _exception;
public Response()
{
_success = false;
}
public Response(bool success)
{
_success = success;
}
public Response(string failureMessage)
{
_failureMessage = failureMessage;
}
public Response(string failureMessage, Exception exception)
{
_failureMessage = failureMessage;
_exception = exception;
}
public bool Success
{
get { return _success; }
}
public string FailureMessage
{
get { return _failureMessage; }
}
public Exception Exception
{
get { return _exception; }
}
public void Failed(string failureMessage)
{
_success = false;
_failureMessage = failureMessage;
}
public void Failed(string failureMessage, Exception exception)
{
_success = false;
_failureMessage = failureMessage;
_exception = exception;
}
}
public class AddMediaCategoryRequestHandler : IRequestHandler<AddMediaCategoryRequest,AddMediaCategoryResponse>
{
private readonly IMediaCategoryRepository _mediaCategoryRepository;
public AddMediaCategoryRequestHandler(IMediaCategoryRepository mediaCategoryRepository)
{
_mediaCategoryRepository = mediaCategoryRepository;
}
public AddMediaCategoryResponse HandleRequest(AddMediaCategoryRequest request)
{
MediaCategory parentCategory = null;
MediaCategory mediaCategory = new MediaCategory(request.Description, request.Label,false);
Guid id = _mediaCategoryRepository.Save(mediaCategory);
if(request.ParentCategory!=Guid.Empty)
{
parentCategory = _mediaCategoryRepository.Get(request.ParentCategory);
parentCategory.AddCategoryTo(mediaCategory);
}
AddMediaCategoryResponse response = new AddMediaCategoryResponse();
response.ID = id;
return response;
}
}
I know this goes on and on but this basic system has served me very well over the last year or so
you can see that the handler than allows the domain object to handle the domain specific logic
The concept you seem to be missing is IoC / DI (i.e. Inversion of Control / Dependency Injection). Instead of using static methods, each of your layers should only depend on an interface of the next layer, with actual instance injected into the constructor. You can call your DL a repository, a provider or anything else as long as it's a clean abstraction of the underlying persistence mechanism.
As for the objects that represent the entities (roughly mapping to tables) I strongly advise against having two sets of objects (one database-specific and one not). It is OK for them to be referenced by all three layers as long as they are POCOs (they should not really know they're persisted), or, even DTOs (pure structures with no behavior whatsoever). Making them DTOs fits your BL concept better, however I prefer having my business logic spread across my domain objects ("the OOP style") rather than having notion of the BL ("the Microsoft style").
Not sure about Llblgen, but NHibernate + any IoC like SpringFramework.NET or Windsor provide pretty clean model that supports this.
This is probably too indirect an answer, but last year I wrestled with these sorts of questions in the Java world and found Martin Fowler's Patterns of Enterprise Application Architecture quite helpful (also see his pattern catalog). Many of the patterns deal with the same issues you're struggling with. They are all nicely abstract and helped me organize my thinking to be able to see the problem at a higher level.
I chose an approach that used the iBatis SQL mapper to encapsulate our interactions with the database. (An SQL mapper drives the programming language data model from the SQL tables, whereas an ORM like yours goes the other way around.) The SQL mapper returns lists and hierarchies of Data Transfer Objects, each of which represents a row of some query result. Parameters to queries (and inserts, updates, deletes) are passed in as DTOs too. The BL layer makes calls on the SQL Mapper (run this query, do that insert, etc.) and passes around DTOs. The DTOs go up to the presentation layer (UI) where they drive the template expansion mechanisms that generate XHTML, XML, and JSON representations of the data. So for us, the only DL dependency that flowed up to the UI was the set of DTOs, but they made the UI a lot more streamlined than passing up unpacked field values would.
If you couple the Fowler book with the specific help other posters can give, you'll do fine. This is an area with a lot of tools and prior experience, so there should be many good paths forward.
Edit: #Ciel, You're quite right, a DTO instance is just a POCO (or in my case a Java POJO). A Person DTO could have a first_name field of "Jim" and so on. Each DTO basically corresponds to a row of a database table and is just a bundle of fields, nothing more. This means it's not coupled closely with the DL and is perfectly appropriate to pass up to the UI. Fowler talks about these on p. 401 (not a bad first pattern to cut your teeth on).
Now I'm not using an ORM, which takes your data objects and creates the database. I'm using an SQL mapper, which is just a very efficient and convenient way to package and execute database queries in SQL. I designed my SQL first (I happen to know it pretty well), then I designed my DTOs, and then set up my iBatis configuration to say that, "select * from Person where personid = #personid#" should return me a Java List of Person DTO objects. I've not yet used an ORM (Hibernate, eg, in the Java world), but with one of those you'd create your data model objects first and the database is built from them.
If your data model objects have all sorts of ORM-specific add-ons, then I can see why you would think twice before exposing them up to the UI layer. But there you could create a C# interface that only defines the POCO get and set methods, and use that in all your non-DL APIs, and create an implementation class that has all the ORM-specific stuff in it:
interface Person ...
class ORMPerson : Person ...
Then if you change your ORM later, you can create alternate POCO implementations:
class NewORMPerson : Person ...
and that would only affect your DL layer code, because your BL and UI code uses Person.
#Zvolkov (below) suggests taking this approach of "coding to interfaces, not implementations" up to the next level, by recommending that you can write your application in such a way that all your code uses Person objects, and that you can use a dependency injection framework to dynamically configure your application to create either ORMPersons or NewORMPersons depending on what ORM you want to use that day
Try centralizing all data access using a repository pattern. As far as your entities are concerned, you can try implementing some kind of translation layer that will map your entities, so it won't break your app. This is just temporary and will allow you to slowly refactor your code.
obviously I do not know the full scope of your code base so consider the pain and the gain.
My opinion only, YMMV.
When I'm messing with any new technology, I figure it should meet two criteria or I'm wasting my time. (Or I don't understand it well enough.)
It should simplify things, or worst case make them no more complicated.
It should not increase coupling or reduce cohesiveness.
It sounds like you feel like you're headed in the opposite direction, which I know is not the intention for either LINQ or ORMs.
My own perception of the value of this new stuff is it helps a developer move the boundary between the DL and the BL into a little more abstract territory. The DL looks less like raw tables and more like objects. That's it. (I usually work pretty hard to do this anyway with a little heavier SQL and stored procedures, but I'm probably more comfortable with SQL than average). But if LINQ and ORM aren't helping you with this yet, I'd say keep at it, but that's where the end of the tunnel is; simplification, and moving the abstraction boundary a bit.
Related
I'm using ASP .NET MVC (C#) and EntityFramework (database first) for a project.
Let's say I'm on a "Movie detail" page which shows the detail of one movie of my database. I can click on each movie and edit each one.
Therefore, I have a Movie class, and a Database.Movie class generated with EF.
My index action looks like :
public ActionResult MovieDetail(int id)
{
Movie movie = Movie.GetInstance(id);
return View("MovieDetail", movie);
}
GetInstance method is supposed to return an instance of Movie class which looks like this for the moment :
public static Movie GetInstance(int dbId)
{
using (var db = new MoviesEntities())
{
Database.Movie dbObject = db.Movies.SingleOrDefault(r => r.Id == dbId);
if (dbObject != null)
{
Movie m = new Movie(dbObject.Id, dbObject.Name, dbObject.Description);
return m;
}
return null;
}
}
It works fine but is this a good way to implement it? Is there an other cleaner way to get my instance of Movie class ?
Thanks
is this a good way to implement it?
That's a very subjective question. It's valid, and there's nothing technically wrong with this implementation. For my small-size home projects, I've used similar things.
But for business applications, it's better to keep your entities unrelated to your MVC application. This means that your data context + EF + generated entities should be kept in a separate project (let's call it the 'Data' project), and the actual data is passed in the form of a DTO.
So if your entity resembles this:
public class Person {
public int Id { get; set; }
public string Name { get; set; }
}
You'd expect there to be an equivalent DTO class that is able to pass that data:
public class PersonDTO {
public int Id { get; set; }
public string Name { get; set; }
}
This means that your 'Data' project only replies with DTO classes, not entities.
public static MovieDTO GetInstance(int dbId)
{
...
}
It makes the most sense that your DTOs are also in a separate project. The reason for all this abstraction is that when you have to change your datacontext (e.g. the application will start using a different data source), you only need to make sure that the new data project also communicates with the same DTOs. How it works internally, and which entities it uses, is only relevant inside the project. From the outside (e.g. from your MVC application), it doesn't matter how you get the data, only that you pass it in a form that your MVC projects already understand (the DTO classes).
All your MVC controller logic will not have to change, because the DTO objects haven't changed. This could save you hours. If you link the entity to your Controller AND View, you'll have to rewrite both if you suddenly decide to change the entity.
If you're worried about the amount of code you'll have to write for converting entities to DTOs and vice versa, you can look into tools like Automapper.
The main question: Is this needed?
That, again, is a very subjective question. It's relative to the scope of the project, but also the expected lifetime of the application. If it's supposed to be used for a long time, it might be worth it to keep everything interchangeable. If this is a small scale, short lifetime project, the added time to implement this might not be worth it.
I can't give you a definitive answer on this. Evaluate how well you want the application to adapt to changes, but also how likely it is that the applicaiton will change in the future.
Disclaimer: This is how we do it at the company where I work. This is not the only solution to this type of problem, but it's the one I'm familiar with. Personally, I don't like making abstractions unless there's a functional reason for it.
A few things:
The naming you're using is a little awkward and confusing. Generally, you don't ever want to have two classes in your project named the same, even if they're in different namespaces. There's nothing technically wrong with it, but it creates confusion. Which Movie do I need here? And if I'm dealing with a Movie instance, is it Movie or Database.Movie? If you stick to names like Movie and MovieDTO or Movie and MovieViewModel, the class names clearly indicate the purpose (lack of suffix indicates a database-backed entity).
Especially if you're coming from another MVC framework like Rails or Django, ASP.NET's particular flavor of MVC can be a little disorienting. Most other MVC frameworks have a true Model, a single class that functions as the container for all the business logic and also acts as a repository (which could be considered business logic, in a sense). ASP.NET MVC doesn't work that way. Your entities (classes that represent database tables) are and should be dumb. They're just a place for Entity Framework to stuff data it pulls from the database. Your Model (the M in MVC) is really more a combination of your view models and your service/DAL layer. Your Movie class (not to be confused with Database.Movie... see why that naming bit is important) on the other hand is trying to do triple duty, acting as the entity, view model and repository. That's simply too much. Your classes should do one thing and do it well.
Again, if you have a class that's going to act as a service or repository, it should be an actual service or repository, with everything those patterns imply. Even then, you should not instantiate your context in a method. The easiest correct way to handle it is to simply have your context be a class instance variable. Something like:
public class MovieRepository
{
private readonly MovieEntities context;
public MovieRepository()
{
this.context = new MovieEntities();
}
}
Even better, though is to use inversion of control and pass in the context:
public class MovieRepository
{
private readonly MovieEntities context;
public MovieRepository(MovieEntities context)
{
this.context = context;
}
}
Then, you can employ a dependency injection framework, like Ninject or Unity to satisfy the dependency for you (preferably with a request-scoped object) whenever you need an instance of MovieRepository. That's a bit high-level if you're just starting out, though, so it's understandable if you hold off on going the whole mile for now. However, you should still design your classes with this in mind. The point of inversion of control is to abstract dependencies (things like the context for a class that needs to pull entities from the database), so that you can switch out these dependencies if the need should arise (say perhaps if there comes a time when you're going to retrieve the entities from an Web API instead of through Entity Framework, or even if you just decide to switch to a different ORM, such as NHibernate). In your code's current iteration, you would have to touch every method (and make changes to your class in general, violating open-closed).
entity-model never should act as view-model. Offering data to the views is an essential role of the view-model. view-model can easily be recognized because it doesn’t have any other role or responsibility other than holding data and business rules that act solely upon that data. It thus has all the advantages of any other pure model such as unit-testability.
A good explanation of this can be found in Dino Esposito’s The Three Models of ASP.NET MVC Apps.
You can use AutoMapper
What is AutoMapper?
AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. This type of code is rather dreary and boring to write, so why not invent a tool to do it for us?
How do I get started?
Check out the getting started guide.
Where can I get it?
First, install NuGet. Then, install AutoMapper from the package manager console:
PM> Install-Package AutoMapper
I'm working on a system where I'd like to have my layers decoupled as much as possible, you know, some kind of modular application to be able to switch databases and stuff without a serious modification of the rest of the system.
So, I've been watching for x-the time one of the talks of Robert C. Martin about good practices, clean code, decoupling architecture etc, to get some inspiration. What I find kinda weird is his description of the system Fitnesse and the way they've implemented store/load methods for WikiPages. I'm linking the video as well: Robert C. Martin - Clean Architecture and Design
What's he describing (at least from my understanding) is that the entity is aware of the mechanism how to store and load itself from some persistent layer. When he wanted to store WikiPages in-memory, he simply overrode the WikiPage and created a new InMemoryWikiPage. When he wanted to store them in a database, he did the same thing...
So, one of my questions is - what is this approach called? I've been learning the whole time about Repository patterns and stuff, and why should be classes like this persistence-ignorant, but I can't seem to find any materials on this thing he did. Because my application will consist of modules, I think this may help to solve my problems without a need for creating some centralized store for my entities... Every module would simply take care of itself including persistence of its entities.
I think the code would look like is something like this:
public class Person : IEntity
{
public int ID { get;set; }
public string Name { get;set; }
public void Save()
{
..
}
public void Update()
{
}
public void Delete()
{
}
...
}
Seems a bit weird, but... Or maybe I misunderstood what he said in the video?
My second question would be, if you don't agree with this approach, what would be the path you'd take in such modular application?
Please provide an example if possible with some explanation.
I'll answer your second question. I think you will be interested as well in Dependency Injection.
I'm not an expert on DI but I'll try to explain as clear as I'm able to.
First off, from wikipedia:
Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time.
The primary purpose of the dependency injection pattern is to allow selection among multiple implementations of a given dependency interface at runtime, or via configuration files, instead of at compile time.
There are many libraries around that help you implement this design pattern: AutoFac, SimpleInjector, Ninject, Spring .NET, and many others.
In theory, this is what your code would look like (AutoFac example)
var containerBuilder = new ContainerBuilder();
//This is your container builder. It will be used to register interfaces
// with concrete implementations
Then, you register concrete implementations for interface types:
containerBuilder.RegisterType<MockDatabase>().As<IDatabase>().InstancePerDependency();
containerBuilder.RegisterType<Person>().As<IPerson>().InstancePerDependency();
In this case, InstancePerDependency means that whenever you try to resolve IPerson, you'll get a new instance. It could be for example SingleInstance, so whenever you tried to resolve IPerson, you would get the same shared instance.
Then you build your container, and use it:
var container = containerBuilder.Build();
IPerson myPerson = container.Resolve<IPerson>(); //This will retrieve the object based on whatever implementation you registered for IPerson
myPerson.Id = 1;
myPerson.Save(); //Save your changes
The model I used in this example:
interface IEntity
{
int Id { get; set; }
string TableName { get; }
//etc
}
interface IPerson: IEntity
{
void Save();
}
interface IDatabase
{
void Save(IEntity entity);
}
class SQLDatabase : IDatabase
{
public void Save(IEntity entity)
{
//Your sql execution (very simplified)
//yada yada INSERT INTO entity.TableName VALUES (entity.Id)
//If you use EntityFramework it will be even easier
}
}
class MockDatabase : IDatabase
{
public void Save(IEntity entity)
{
return;
}
}
class Person : IPerson
{
IDatabase _database;
public Person(IDatabase database)
{
this._database = database;
}
public void Save()
{
_database.Save(this);
}
public int Id
{
get;
set;
}
public string TableName
{
get { return "Person"; }
}
}
Don't worry, AutoFac will automatically resolve any Person Dependencies, such as IDatabase.
This way, in case you wanted to switch your database, you could simply do this:
containerBuilder.RegisterType<SqlDatabase>().As<IDatabase>().InstancePerDependency();
I wrote an over simplified (not suitable for use) code which serves just as a kickstart, google "Dependency Injection" for further information. I hope this helps. Good luck.
The pattern you posted is an Active Record.
The difference between Repository and Active Record Pattern is that in Active Record pattern, data query and persistence, and the domain object are in one class, where as in Repository, the data persistence and query are decoupled from the domain object itself.
Another pattern that you may want to look into is the Query Object which, unlike respository pattern where its number of methods will increase in every possible query (filter, sorting, grouping, etc) the query object can use fluent interface to be expressive [1] or dedicated in which one you may pass parameter [2]
Lastly, you may look at Command Query Responsibility Segregation architecture for ideas. I personally loosely followed it, just picked up ideas that can help me.
Hope this helps.
Update base on comment
One variation of Repository pattern is this
UserRepository
{
IEnumerable<User> GetAllUsers()
IEnumerable<User> GetAllByStatus(Status status)
User GetUserById(int id)
...
}
This one does not scale since the repository get's updated for additional query that way be requested
Another variation is to pass query object as parameter to the data query
UserRepository
{
IEnumerable<User> GetAll(QueryObject)
User GetUserById(int id)
...
}
var query = new UserQueryObject(status: Status.Single)
var singleUsers = userRepo.GetAll(query)
Some in .Net world, Linq expression is passed instead of QueryObject
var singleUsers = userRepo.GetAll(user => user.Status == Status.Single)
Another variation is to do dedicate Repository for retrieval on one entity by its unique identifier and save it, while query object is used to submit data retrieval, just like in CQRS.
Update 2
I suggest you get familiar with the SOLID principles. These principles are very helpful in guiding you creating a loosely coupled, high cohesive architecture.
Los Techies compilation on SOLID pricples contains good introductory articles regarding SOLID priciples.
Let's say that I want to create a blog application with these two simple persistence classes used with EF Code First or NHibernate and returned from repository layer:
public class PostPersistence
{
public int Id { get; set; }
public string Text { get; set; }
public IList<LikePersistence> Likes { get; set; }
}
public class LikePersistence
{
public int Id { get; set; }
//... some other properties
}
I can't figure out a clean way to map my persistence models to domain models. I'd like my Post domain model interface to look something like this:
public interface IPost
{
int Id { get; }
string Text { get; set; }
public IEnumerable<ILike> Likes { get; }
void Like();
}
Now how would an implementation underneath look like? Maybe something like this:
public class Post : IPost
{
private readonly PostPersistence _postPersistence;
private readonly INotificationService _notificationService;
public int Id
{
get { return _postPersistence.Id }
}
public string Text
{
get { return _postPersistence.Text; }
set { _postPersistence.Text = value; }
}
public IEnumerable<ILike> Likes
{
//this seems really out of place
return _postPersistence.Likes.Select(likePersistence => new Like(likePersistence ));
}
public Post(PostPersistence postPersistence, INotificationService notificationService)
{
_postPersistence = postPersistence;
_notificationService = notificationService;
}
public void Like()
{
_postPersistence.Likes.Add(new LikePersistence());
_notificationService.NotifyPostLiked(Id);
}
}
I've spent some time reading about DDD but most examples were theoretical or used same ORM classes in domain layer. My solution seems to be really ugly, because in fact domain models are just wrappers around ORM classes and it doens't seem to be a domain-centric approach. Also the way IEnumerable<ILike> Likes is implemented bothers me because it won't benefit from LINQ to SQL. What are other (concrete!) options to create domain objects with a more transparent persistence implementation?
One of the goals of persistence in DDD is persistence ignorance which is what you seem to be striving for to some extent. One of the issues that I see with your code samples is that you have your entities implementing interfaces and referencing repositories and services. In DDD, entities should not implement interfaces which are just abstractions of itself and have instance dependencies on repositories or services. If a specific behavior on an entity requires a service, pass that service directly into the corresponding method. Otherwise, all interactions with services and repositories should be done outside of the entity; typically in an application service. The application service orchestrates between repositories and services in order to invoke behaviors on domain entities. As a result, entities don't need to references services or repositories directly - all they have is some state and behavior which modifies that state and maintains its integrity. The job of the ORM then is to map this state to table(s) in a relational database. ORMs such as NHibernate allow you to attain a relatively large degree of persistence ignorance.
UPDATES
Still I don't want to expose method with an INotificationService as a
parameter, because this service should be internal, layer above don't
need to know about it.
In your current implementation of the Post class the INotificationService has the same or greater visibility as the class. If the INotificationService is implemented in an infrastructure layer, it already has to have sufficient visibility. Take a look at hexagonal architecture for an overview of layering in modern architectures.
As a side note, functionality associated with notifications can often be placed into handlers for domain events. This is a powerful technique for attaining a great degree of decoupling.
And with separate DTO and domain classes how would you solve
persistence synchronization problem when domain object doesn't know
about its underlying DTO? How to track changes?
A DTO and corresponding domain classes exist for very different reasons. The purpose of the DTO is to carry data across system boundaries. DTOs are not in a one-one correspondence with domain objects - they can represent part of the domain object or a change to the domain object. One way to track changes would be to have a DTO be explicit about the changes it contains. For example, suppose you have a UI screen that allows editing of a Post. That screen can capture all the changes made and send those changes in a command (DTO) to a service. The service would load up the appropriate Post entity and apply the changes specified by the command.
I think you need to do a bit more research, see all the options and decide if it is really worth the hassle to go for a full DDD implementation, i ve been there myself the last few days so i ll tell you my experience.
EF Code first is quite promising but there are quite a few issues with it, i have an entry here for this
Entity Framework and Domain Driven Design. With EF your domain models can be persisted by EF without you having to create a separate "persistence" class. You can use POCO (plain old objects) and get a simple application up and running but as i said to me it s not fully mature yet.
If you use LINQ to SQL then the most common approach would be to manually map a "data transfer object" to a business object. Doing it manually can be tough for a big application so check for a tool like Automapper. Alternatively you can simply wrap the DTO in a business object like
public class Post
{
PostPersistence Post { get; set;}
public IList<LikePersistence> Likes { get; set; }
.....
}
NHibernate: Not sure, havent used it for a long time.
My feeling for this (and this is just an opinion, i may be wrong) is that you ll always have to make compromises and you ll not find a perfect solution out there. If you give EF a couple more years it may get there. I think an approach that maps DTOs to DDD objects is probably the most flexible so looking for an automapping tool may be worth your time. If you want to keep it simple, my favourite would be some simple wrappers around DTOs when required.
I am writing a new website project pretty much from scratch. The project is in C# but my background is in PHP (the pseudo-code below is a bit if a mixture, trying to be both succinct and declarative).
The problem
I need to retrieve configuration data from one of two places - sometimes from the local Database and sometimes from a Soap service. I should be able to create the same set of Model objects from either source.
The data is stored in completely different structures in the different data sources - several different Soap responses need to be pieced together from the Soap end, whereas the DB structure is much closer to how I'm structuring my Model objects in the code.
The configuration is made up of a tree of objects: Products contain Properties which contain Options which have Conditions for when they apply.
The goals
I want to separate concerns as much as possible (to hopefully facilitate both test-/maintain-/extend-ability):
My Model objects should know nothing about Data Persistence or retrieval
The Data Persistence object should, as far as possible, be agnostic about the exact type of Data Source
I want to separate object creation out as much as possible.
Questions
I'm aware of various design patterns around this (although I'm not entirely sure I understand them entirely). I asked a question on Programmers similar to this and got a response about Persistence Ignorance (more here) and the Repository pattern, which both seem to be concepts from the Microsoft world.
As far as I can tell "Persistence Ignorance" is simply the concept of having Model objects that know nothing about your Data Storage mechanism, and the Repository pattern seems very similar to the Data Mapper pattern, except that it may be more of a facade, hiding more of what's actually going on.
So my questions are:
In the Data Mapper pattern should I have one Mapper per Model object? Rather than having one for the entire configuration tree?
And therefore, should I have a configuration tree building object that uses all those Mapper objects?
class ConfigBuilder() {
public ConfigBuilder (productMapper, propertyMapper, optionMapper, conditionMapper) {
// save them into local properties
}
public Products() {
var products = productMapper.FetchAll();
foreach (var product in products) {
AddProperties(product);
}
return products;
}
private AddProperties(products) { /* ... */ }
private AddOptions(property) { /* ... */ }
private AddConditions(option) { /* ... */ }
}
Does this seem like a good solution?
Where should the logic to build the objects be located?
At some point there needs to be a considerable amount of logic to build my configuration objects from the random array of XML data that I get back from the Soap service, and a smaller amount of logic to do the same from the database.
Should I be putting the logic to build the objects in separate instances of the Mapper objects?
interface IProductMapper { FetchAll; FetchByCode; Create; Delete; Update }
class ProductMapperXml implements IProductMapper {
public ProductMapperXml(xmlDataSource) {}
public FetchAll() { /* A whole bunch of logic to create the Product objects from XML data source */ }
}
class ProductMapperDatabase implements IProductMapper {
public ProductMapperDatabase(databaseConnection) {}
public FetchAll() { /* Select and build products from the database */ }
}
Is this okay? Should this logic be abstracted further? If so why? Also, I'm a bit uneasy about the ProductMapperXml object having considerable logic itself and also being responsible for creating Product objects internally. Should I be passing it a ProductFactory of some sort? Or just use a factory method?
Please please let me know if there are more elegant ways to solve this than my suggestions? Also if there are any layers of abstraction or Design Patterns I could benefit from that I've missed?
Since no answers are forthcoming I'm going to write this up myself.
I did end up going with the DataMapper pattern - I hope I implemented it in a sensible fashion.
I didn't end up using any Factory class, because I was able to build the tree through the classes themselves.
I created a bunch of Mapper interfaces:
interface Models.Interfaces.IModel {}
interface Mappers.Interfaces.IMapper {}
interface Mappers.Interfaces.IDatabaseMapper : IMapper {}
interface Mappers.Interfaces.IXmlMapper : IMapper {}
I created Models for everything:
class Models.Product : IModel {}
class Models.Property : IModel {}
class Models.Option : IModel {}
class Models.Condition : IModel {}
And then I gave each model two mapper classes:
class Mappers.ProductDatabaseMapper : IDatabaseMapper {}
class Mappers.ProductXmlMapper : IXmlMapper {}
/* ... (same for each model) */
Each Mapper class has methods to create its children:
class ProductDatabaseMapper :IDatabaseMapper {
public List<Product> FetchAllWithChildren {
var productRows = DbManager.FetchAll("Product");
var products = List<Product>();
foreach(var productRow in productRows) {
var product = new Product(productRow["Name"]);
product.Properties = PropertyManagerInstance.FetchAllWithChildren(product);
products.Add(product):
}
return products;
}
}
I think this presents a fairly neat solution. Although I'm still a little worried about the fact that my various Mapper classes are creating objects themselves. But I think I'll only separate that out into a factory as and when it becomes necessary.
Is it possible to expose the DataContext when extending a class in the DataContext? Consider this:
public partial class SomeClass {
public object SomeExtraProperty {
this.DataContext.ExecuteQuery<T>("{SOME_REALLY_COMPLEX_QUERY_THAT_HAS_TO_BE_IN_RAW_SQL_BECAUSE_LINQ_GENERATES_CRAP_IN_THIS INSTANCE}");
}
}
How can I go about doing this? I have a sloppy version working now, where I pass the DataContext to the view model and from there I pass it to the method I have setup in the partial class. I'd like to avoid the whole DataContext passing around and just have a property that I can reference.
UPDATE FOR #Aaronaught
So, how would I go about writing the code? I know that's a vague question, but from what I've seen online so far, all the tutorials feel like they assume I know where to place the code and how use it, etc.
Say I have a very simple application structured as (in folders):
Controllers
Models
Views
Where do the repository files go? In the Models folder or can I create a "Repositories" folder just for them?
Past that how is the repository aware of the DataContext? Do I have to create a new instance of it in each method of the repository (if so that seems in-efficient... and wouldn't that cause problems with pulling an object out of one instance and using it in a controller that's using a different instance...)?
For example I currently have this setup:
public class BaseController : Controller {
protected DataContext dc = new DataContext();
}
public class XController : BaseController {
// stuff
}
This way I have a "global" DataContext available to all controllers who inherit from BaseController. It is my understanding that that is efficient (I could be wrong...).
In my Models folder I have a "Collections" folder, which really serve as the ViewModels:
public class BaseCollection {
// Common properties for the Master page
}
public class XCollection : BaseCollection {
// X View specific properties
}
So, taking all of this where and how would the repository plug-in? Would it be something like this (using the real objects of my app):
public interface IJobRepository {
public Job GetById(int JobId);
}
public class JobRepository : IJobRepository {
public Job GetById(int JobId) {
using (DataContext dc = new DataContext()) {
return dc.Jobs.Single(j => (j.JobId == JobId));
};
}
}
Also, what's the point of the interface? Is it so other services can hook up to my app? What if I don't plan on having any such capabilities?
Moving on, would it be better to have an abstraction object that collects all the information for the real object? For example an IJob object which would have all of the properties of the Job + the additional properties I may want to add such as the Name? So would the repository change to:
public interface IJobRepository {
public IJob GetById(int JobId);
}
public class JobRepository : IJobRepository {
public IJob GetById(int JobId) {
using (DataContext dc = new DataContext()) {
return dc.Jobs.Single(j => new IJob {
Name = dc.SP(JobId) // of course, the project here is wrong,
// but you get the point...
});
};
}
}
My head is so confused now. I would love to see a tutorial from start to finish, i.e., "File -> New -> Do this -> Do that".
Anyway, #Aaronaught, sorry for slamming such a huge question at you, but you obviously have substantially more knowledge at this than I do, so I want to pick your brain as much as I can.
Honestly, this isn't the kind of scenario that Linq to SQL is designed for. Linq to SQL is essentially a thin veneer over the database; your entity model is supposed to closely mirror your data model, and oftentimes your Linq to SQL "entity model" simply isn't appropriate to use as your domain model (which is the "model" in MVC).
Your controller should be making use of a repository or service of some kind. It should be that object's responsibility to load the specific entities along with any additional data that's necessary for the view model. If you don't have a repository/service, you can embed this logic directly into the controller, but if you do this a lot then you're going to end up with a brittle design that's difficult to maintain - better to start with a good design from the get-go.
Do not try to design your entity classes to reference the DataContext. That's exactly the kind of situation that ORMs such as Linq to SQL attempt to avoid. If your entities are actually aware of the DataContext then they're violating the encapsulation provided by Linq to SQL and leaking the implementation to public callers.
You need to have one class responsible for assembling the view models, and that class should either be aware of the DataContext itself, or various other classes that reference the DataContext. Normally the class in question is, as stated above, a domain repository of some kind that abstracts away all the database access.
P.S. Some people will insist that a repository should exclusively deal with domain objects and not presentation (view) objects, and refer to the latter as services or builders; call it what you like, the principle is essentially the same, a class that wraps your data-access classes and is responsible for loading one specific type of object (view model).
Let's say you're building an auto trading site and need to display information about the domain model (the actual car/listing) as well as some related-but-not-linked information that has to be obtained separately (let's say the price range for that particular model). So you'd have a view model like this:
public class CarViewModel
{
public Car Car { get; set; }
public decimal LowestModelPrice { get; set; }
public decimal HighestModelPrice { get; set; }
}
Your view model builder could be as simple as this:
public class CarViewModelService
{
private readonly CarRepository carRepository;
private readonly PriceService priceService;
public CarViewModelService(CarRepository cr, PriceService ps) { ... }
public CarViewModel GetCarData(int carID)
{
var car = carRepository.GetCar(carID);
decimal lowestPrice = priceService.GetLowestPrice(car.ModelNumber);
decimal highestPrice = priceService.GetHighestPrice(car.ModelNumber);
return new CarViewModel { Car = car, LowestPrice = lowestPrice,
HighestPrice = highestPrice };
}
}
That's it. CarRepository is a repository that wraps your DataContext and loads/saves Cars, and PriceService essentially wraps a bunch of stored procedures set up in the same DataContext.
It may seem like a lot of effort to create all these classes, but once you get into the swing of it, it's really not that time-consuming, and you'll ultimately find it way easier to maintain.
Update: Answers to New Questions
Where do the repository files go? In the Models folder or can I create a "Repositories" folder just for them?
Repositories are part of your model if they are responsible for persisting model classes. If they deal with view models (AKA they are "services" or "view model builders") then they are part of your presentation logic; technically they are somewhere between the Controller and Model, which is why in my MVC apps I normally have both a Model namespace (containing actual domain classes) and a ViewModel namespace (containing presentation classes).
how is the repository aware of the DataContext?
In most instances you're going to want to pass it in through the constructor. This allows you to share the same DataContext instance across multiple repositories, which becomes important when you need to write back a View Model that comprises multiple domain objects.
Also, if you later decide to start using a Dependency Injection (DI) Framework then it can handle all of the dependency resolution automatically (by binding the DataContext as HTTP-request-scoped). Normally your controllers shouldn't be creating DataContext instances, they should actually be injected (again, through the constructor) with the pre-existing individual repositories, but this can get a little complicated without a DI framework in place, so if you don't have one, it's OK (not great) to have your controllers actually go and create these objects.
In my Models folder I have a "Collections" folder, which really serve as the ViewModels
This is wrong. Your View Model is not your Model. View Models belong to the View, which is separate from your Domain Model (which is what the "M" or "Model" refers to). As mentioned above, I would suggest actually creating a ViewModel namespace to avoid bloating the Views namespace.
So, taking all of this where and how would the repository plug-in?
See a few paragraphs above - the repository should be injected with the DataContext and the controller should be injected with the repository. If you're not using a DI framework, you can get away with having your controller create the DataContext and repositories, but try not to cement the latter design too much, you'll want to clean it up later.
Also, what's the point of the interface?
Primarily it's so that you can change your persistence model if need be. Perhaps you decide that Linq to SQL is too data-oriented and you want to switch to something more flexible like Entity Framework or NHibernate. Perhaps you need to implement support for Oracle, mysql, or some other non-Microsoft database. Or, perhaps you fully intend to continue using Linq to SQL, but want to be able to write unit tests for your controllers; the only way to do that is to inject mock/fake repositories into the controllers, and for that to work, they need to be abstract types.
Moving on, would it be better to have an abstraction object that collects all the information for the real object? For example an IJob object which would have all of the properties of the Job + the additional properties I may want to add such as the Name?
This is more or less what I recommended in the first place, although you've done it with a projection which is going to be harder to debug. Better to just call the SP on a separate line of code and combine the results afterward.
Also, you can't use an interface type for your Domain or View Model. Not only is it the wrong metaphor (models represent the immutable laws of your application, they are not supposed to change unless the real-world requirements change), but it's actually not possible; interfaces can't be databound because there's nothing to instantiate when posting.
So yeah, you've sort of got the right idea here, except (a) instead of an IJob it should be your JobViewModel, (b) instead of an IJobRepository it should be a JobViewModelService, and (c) instead of directly instantiating the DataContext it should accept one through the constructor.
Keep in mind that the purpose of all of this is to keep a clean, maintainable design. If you have a 24-hour deadline to meet then you can still get it to work by just shoving all of this logic directly into the controller. Just don't leave it that way for long, otherwise your controllers will (d)evolve into God-Object abominations.
Replace {SOME_REALLY_COMPLEX_QUERY_THAT_HAS_TO_BE_IN_RAW_SQL_BECAUSE_LINQ_GENERATES_CRAP_IN_THIS INSTANCE} with a stored procedure then have Linq to SQL import that function.
You can then call the function directly from the data context, get the results and pass it to the view model.
I would avoid making a property that calls the data context. You should just get the value from a service or repository layer whenever you need it instead of embedding it into one of the objects created by Linq to SQL.