I'm having trouble understanding how to design my domain objects correctly. The issue i keep grappling with is how to populate my domain objects with data. The examples i've found have been to trivial to really help me out. I've tried a variety of methods but i don't love any of them. Say you have a large set of data you need to pass into your class so you bundle it in a POCO.
My first direction (pass data into the constructor):
public class MyClass
{
private readonly ICalculator _calculator;
private readonly MyClassDataPOCO _data;
public MyClass(ICalculator _calculator, MyClassDataPOCO data)
{
this._calculator = _calculator;
_data = data
This doesn't work out well because then your IOC containers can't automatically initialize your classes.
Second Direction (pass data into the operation):
public class MyClass
{
private readonly ICalculator _calculator;
public MyClass(ICalculator _calculator)
{
this._calculator = _calculator;
}
public decimal CalculateComplicatedValue1(MyClassDataPOCO data)
{
}
public decimal CalculateComplicatedValue2(MyClassDataPOCO data)
{
}
I didn't like this for a variety of reasons
Your class become nothing more than instance functions (not really classes). They only have behavior and not data.
Your entrusting your client to your data. Doesn't seem like a smart idea. I'm sure you would eventually run into mutated state problems.
Third Direction (only allow you're class to be created through a static factory method):
public class MyClass
{
private readonly ICalculator _calculator;
private MyClassDataPOCO _data;
private MyClass(ICalculator _calculator)
{
this._calculator = _calculator;
}
public static MyClass Create(MyClassDataPOCO data)
{
return Create(_container.GetInstance<ICalculator>(), data);
}
public static MyClass Create(ICalculator calculator, MyClassDataPOCO data)
{
//do some input validation here
var myReturn = new MyClass(calculator);
myReturn._data = data;
return myReturn;
}
I guess out of all the options i like this one the best. The only thing i don't like is having to have two create functions so it can be unit tested (so i can inject ICalculator).
The only option i didn't try was property injection because id didn't think it was a good idea to inject your data in through properties.
You design a domain object (DO) based on business concept and use cases. From my experience, this means your objects should be quite slim. The DO is implemented based on concept definition. A business use case is implemented in a service (can be app service, can be domain service, it depends on the context) which will use the DO in order to update stuff.
When I design an object, I just think of what input I need for what behaviour. All objects should have an initial state so you pass a DTO (everything is a POCO, we don't care about persistence here) with initial values. Actually, it's the same for every method.
About persistence, since I'm using CQRS, I only care about save/get an object. Personally I prefer to json the object (if I don't use event sourcing) so save=serialize, get=deserialize. About encapsulation, you can configure the json serializer to work with private properties and basically having private properties is the only compromise you make.
As I've said before, a use case is implemented as a service, so in your scenario, MyClass is actually a service, not a DO. As a thumb rule, a DO contains only data and behaviour which help define the object. CalculateComplicatedValue doesn't look like a part of a concept, but it does look like a use case therefore a service.
You don't need a factory here, instantiating a DO is usually straightforward, however a service usually is instantiated by a DI Container, because in most cases a service does use other services (like a repository or a validator).
Related
I have a little problem understanding repository-domain object relation. Here is some information I know about domain design(they may also be wrong or not accurate). And with these in mind, I can't find a way to obtain a domain object from the repository.
In DDD the domain should know and contain only whats needed for the business and everything else must be cleared out of the domain. That's fine. And also abstracting data access from any business is a good practice too. The application doesn't need to know where we store data or how we store data. We only ask the repository to give us a domain object and it gives us the object we want or the other way is valid too, we give the repository a domain object and it sends it to the storage.
Declaring public setters for domain objects is also a very bad approach in object oriented design since we won't be able to control who is accessing what and changing what. So it is a good practice to expose only whats needed for outside of the object.
So with these in my mind, I can't figure out a way to implement my repositories. I can use any ORM or pure sql in my code and retrieve data.
But I can't create domain objects from persistence objects;
Since they don't have public setters, I can't create and set the field values.
Declaring public constructors containing all of the fields doesn't seems right. I might have several models to fill in, this means I have to define several constructors with different sets of parameters.
Any help will be appreciated...
There are options you have:
1. ORMs can work with private fields.
As I know, ORMs (e.g. Entity Framework, NHibernate) can set properties via non-public setters.
There is an example that proves it for Entity Framework - Entity Framework, Private Constructors and Private Setters.
If you use NHibernate your setters should be public/protected virtual/protected internal virtual or private backing field can be used. You can find more information in the Property Access strategies in NHibernate SO question.
2. Reflection can be used.
It can be used to get access to private fields/properties also. It is possible to set private property via reflection.
3. It is not a bad practice to have public constructor to construct your entity.
Declaring public constructors containing all of the fields doesn't seems right. I might have several models to fill in, this means I have to define several constructors with different sets of parameters.
Your Domain Entities need only one public constructor with full list of properties they have. It is enough to have only one constructor in spite of having several models to fill in. It is a responsibility of repository to invoke constructor and map model into its parameters correctly.
Edit:
4. Automapper can be used.
The following test shows that AutoMapper can map properties via private setters.
[TestClass]
public class AutomapperTest
{
[TestMethod]
public void Test()
{
// arrange
Mapper.CreateMap<AModel, A>();
var model = new AModel { Value = 100 };
//act
var entity = Mapper.Map<A>(model);
// assert
entity.Value.Should().Be(100);
entity.Value.Should().Be(model.Value);
}
}
public class AModel
{
public int Value { get; set; }
}
public class A
{
public int Value { get; private set; }
}
It's not true you can't create domain objects with ORM not having public setters. If you're using Entity Framework, it definitely can map private properties in model first approach and you only need public getters in code first approach. I don't know how about other ORM-s.
I am trying to understand your query here. Some tips on how you can proceed.
First of all the Domain should know the repository contracts and not the actual repository infrastructure. in other words, you may choose to have 3 class libs as follows
XYZDomain (will know XYZRepository and make call on the appropriate
methods of this interface)
XYZRepository (contains Interface IXYZService interface)
XYZSQLRepository(actual implementation of XYZRepository interfaces).
Now it's up to you to choose where to inject XYZSQLRepository to the XYZDomain using Dependency injection.
You can also try using eventing model to register these repositories if you want.
Use a custom Service Locator to get the concrete objects
Okay, I'm going to try and go short and straight to the point. I am trying to develop a loosely-coupled, multi-tier service application that is testable and supports dependency injection. Here's what I have:
At the service layer, I have a StartSession method that accepts some key data required to, well, start the session. My service class is a facade and delegates to an instance of the ISessionManager interface that is injected into the service class constructor.
I am using the Repository pattern in the data access layer. So I have an ISessionRepository that my domain objects will work with and that I implement using the data access technology du jour. ISessionRepository has methods for GetById, Add and Update.
Since my service class is just a facade, I think it is safe to say that my ISessionManager implementation is the actual service class in my architecture. This class coordinates the operations with my Session domain/business object. And here's where the shell game and problem comes in.
In my SessionManager class (the concrete ISessionManager), here's how I have StartSession implemented:
public ISession StartSession(object sessionStartInfo)
{
var session = Session.GetSession(sessionStartInfo);
if (session == null)
session = Session.NewSession(sessionStartInfo);
return session;
}
I have three problems with this code:
First, obviously I could move this logic into a StartSession method in my Session class but I think that would defeat the purpose of the SessionManager class which then simply becomes a second facade (or is it still considered a coordinator?). Alas, the shell game.
Second, SessionManager has a tightly-coupled dependance upon the Session class. I considered creating an ISessionFactory/SessionFactory that could be injected into SessionManager but then I'd have the same tight-coupling inside the factory. But, maybe that's okay?
Finally, it seems to me that true DI and factory methods don't mix. After all, we want to avoid "new"ing an instance of an object and let the container return the instance to us. And true DI says that we should not reference the container directly. So, how then do I get the concrete ISessionRepository class injected into my Session domain object? Do I have it injected into the factory class then manually pass it into Session when constructing a new instance (using "new")?
Keep in mind that this is also only one operation and I also need to perform other tasks such as saving a session, listing sessions based on various criteria plus work with other domain objects in my solution. Plus, the Session object also encapsulates business logic for authorization, validation, etc. so (I think) it needs to be there.
The key to what I am looking to accomplish is not only functional but testable. I am using DI to break dependencies so we can easily implement unit tests using mocks as well as give us the ability to make changes to the concrete implementations without requiring changes in multiple areas.
Can you help me wrap my head around the best practices for such a design and how I can best achieve my goals for a solid SOA, DDD and TDD solution?
UPDATE
I was asked to provide some additional code, so as succinctly as possible:
[ServiceContract()]
public class SessionService : ISessionService
{
public SessionService(ISessionManager manager) { Manager = manager; }
public ISessionManager Manager { get; private set; }
[OperationContract()]
public SessionContract StartSession(SessionCriteriaContract criteria)
{
var session = Manager.StartSession(Mapper.Map<SessionCriteria>(criteria));
return Mapper.Map<SessionContract>(session);
}
}
public class SessionManager : ISessionManager
{
public SessionManager() { }
public ISession StartSession(SessionCriteria criteria)
{
var session = Session.GetSession(criteria);
if (session == null)
session = Session.NewSession(criteria);
return session;
}
}
public class Session : ISession
{
public Session(ISessionRepository repository, IValidator<ISession> validator)
{
Repository = repository;
Validator = validator;
}
// ISession Properties
public static ISession GetSession(SessionCriteria criteria)
{
return Repository.FindOne(criteria);
}
public static ISession NewSession(SessionCriteria criteria)
{
var session = ????;
// Set properties based on criteria object
return session;
}
public Boolean Save()
{
if (!Validator.IsValid(this))
return false;
return Repository.Save(this);
}
}
And, obviously, there is an ISessionRepository interface and concrete XyzSessionRepository class that I don't think needs to be shown.
2nd UPDATE
I added the IValidator dependency to the Session domain object to illustrate that there are other components in use.
The posted code clarifies a lot. It looks to me like the session class holds state (with behavior), and the service and manager classes strictly perform actions/behavior.
You might look at removing the Repository dependency from the Session and adding it to the SessionManager. So instead of the Session calling Repository.Save(this), your Manager class would have a Save(ISession session) method that would then call Repository.Save(session). This would mean that the session itself would not need to be managed by the container, and it would be perfectly reasonable to create it via "new Session()" (or using a factory that does the same). I think the fact that the Get- and New- methods on the Session are static is a clue/smell that they may not belong on that class (does this code compile? Seems like you are using an instance property within a static method).
Finally, it seems to me that true DI
and factory methods don't mix. After
all, we want to avoid "new"ing an
instance of an object and let the
container return the instance to us.
And true DI says that we should not
reference the container directly. So,
how then do I get the concrete
ISessionRepository class injected into
my Session domain object? Do I have it
injected into the factory class then
manually pass it into Session when
constructing a new instance (using
"new")?
This question gets asked a LOT when it comes to managing classes that mix state and service via an IOC container. As soon as you use an abstract factory that uses "new", you lose the benefits of a DI framework from that class downward in the object graph. You can get away from this by completely separating state and service, and having only your classes that provide service/behavior managed by the container. This leads to passing all data through method calls (aka functional programming). Some containers (Windsor for one) also provide a solution to this very problem (in Windsor it's called the Factory Facility).
Edit: wanted to add that functional programming also leads to what Fowler would call "anemic domain models". This is generally considered a bad thing in DDD, so you might have to weigh that against the advice I posted above.
Just some comments...
After all, we want to avoid "new"ing an instance of an object and let the container return the instance to us.
this ain't true for 100%. You want to avoid "new"ing only across so called seams which basically are lines between layers. if You try to abstract persistence with repositories - that's a seam, if You try to decouple domain model from UI (classic one - system.web reference), there's a seam. if You are in same layer, then decoupling one implementation from another sometimes makes little sense and just adds additional complexity (useless abstraction, ioc container configuration etc.). another (obvious) reason You want to abstract something is when You already right now need polymorphism.
And true DI says that we should not reference the container directly.
this is true. but another concept You might be missing is so called composition root (it's good for things to have a name :). this concept resolves confusion with "when to use service locator". idea is simple - You should compose Your dependency graph as fast as possible. there should be 1 place only where You actually reference ioc container.
E.g. in asp.net mvc application, common point for composition is ControllerFactory.
Do I have it injected into the factory class then manually pass it into Session when constructing a new instance
As I see so far, factories are generally good for 2 things:
1.To create complex objects (Builder pattern helps significantly)
2.Resolving violations of open closed and single responsibility principles
public void PurchaseProduct(Product product){
if(product.HasSomething) order.Apply(new FirstDiscountPolicy());
if(product.HasSomethingElse) order.Apply(new SecondDiscountPolicy());
}
becomes as:
public void PurchaseProduct(Product product){
order.Apply(DiscountPolicyFactory.Create(product));
}
In that way Your class that holds PurchaseProduct won't be needed to be modified if new discount policy appears in sight and PurchaseProduct would become responsible for purchasing product only instead of knowing what discount to apply.
P.s. if You are interested in DI, You should read "Dependency injection in .NET" by Mark Seemann.
I thought I'd post the approach I ended up following while giving due credit above.
After reading some additional articles on DDD, I finally came across the observation that our domain objects should not be responsible for their creation or persistence as well as the notion that it is okay to "new" an instance of a domain object from within the Domain Layer (as Arnis eluded).
So, I retained my SessionManager class but renamed it SessionService so it would be clearer that it is a Domain Service (not to be confused with the SessionService in the facade layer). It is now implemented like:
public class SessionService : ISessionService
{
public SessionService(ISessionFactory factory, ISessionRepository repository)
{
Factory = factory;
Repository = repository;
}
public ISessionFactory Factory { get; private set; }
public ISessionRepository Repository { get; private set; }
public ISession StartSession(SessionCriteria criteria)
{
var session = Repository.GetSession(criteria);
if (session == null)
session = Factory.CreateSession(criteria);
else if (!session.CanResume)
thrown new InvalidOperationException("Cannot resume the session.");
return session;
}
}
The Session class is now more of a true domain object only concerned with the state and logic required when working with the Session, such as the CanResume property shown above and validation logic.
The SessionFactory class is responsible for creating new instances and allows me to still inject the ISessionValidator instance provided by the container without directly referencing the container itself:
public class SessionFactory : ISessionFactory
{
public SessionFactory(ISessionValidator validator)
{
Validator = validator;
}
public ISessionValidator Validator { get; private set; }
public Session CreateSession(SessionCriteria criteria)
{
var session = new Session(Validator);
// Map properties
return session;
}
}
Unless someone can point out a flaw in my approach, I'm pretty comfortable that this is consistent with DDD and gives me full support for unit testing, etc. - everything I was after.
In the projects I worked on I have classes that query/update database, like this one,
public class CompanyInfoManager
{
public List<string> GetCompanyNames()
{
//Query database and return list of company names
}
}
as I keep creating more and more classes of this sort, I realize that maybe I should make this type of class static. By doing so the obvious benefit is avoid the need to create class instances every time I need to query the database. But since for the static class, there is only one copy of the class, will this result in hundreds of requests contend for only one copy of static class?
Thanks,
I would not make that class static but instead would use dependency injection and pass in needed resources to that class. This way you can create a mock repository (that implements the IRepository interface) to test with. If you make the class static and don't pass in your repository then it is very difficult to test since you can't control what the static class is connecting to.
Note: The code below is a rough example and is only intended to convey the point, not necessarily compile and execute.
public interface IRepository
{
public DataSet ExecuteQuery(string aQuery);
//Other methods to interact with the DB (such as update or insert) are defined here.
}
public class CompanyInfoManager
{
private IRepository theRepository;
public CompanyInfoManager(IRepository aRepository)
{
//A repository is required so that we always know what
//we are talking to.
theRepository = aRepository;
}
public List<string> GetCompanyNames()
{
//Query database and return list of company names
string query = "SELECT * FROM COMPANIES";
DataSet results = theRepository.ExecuteQuery(query);
//Process the results...
return listOfNames;
}
}
To test CompanyInfoManager:
//Class to test CompanyInfoManager
public class MockRepository : IRepository
{
//This method will always return a known value.
public DataSet ExecuteQuery(string aQuery)
{
DataSet returnResults = new DataSet();
//Fill the data set with known values...
return returnResults;
}
}
//This will always contain known values that you can test.
IList<string> names = new CompanyInfoManager(new MockRepository()).GetCompanyNames();
I didn't want to ramble on about dependency injection. Misko Hevery's blog goes into great detail with a great post to get started.
It depends. Will you ever need to make your program multithreaded? Will you ever need to connect to more than one database? Will you ever need to store state in this class? Do you need to control the lifetime of your connections? Will you need data caching in the future? If you answer yes to any of these, a static class will make things awkward.
My personal advice would be to make it an instance as this is more OO and would give you flexibility you might need in the future.
You have to be careful making this class static. In a web app, each request is handled on its own thread. Static utilities can be thread-unsafe if you are not careful. And if that happens you are not going to be happy.
I would highly recommend you follow the DAO pattern. Use a tool like Spring to make this easy for you. All you have to do is configure a datasource and your DB access and transactions will be a breeze.
If you go for a static class you will have to design it such that its largely stateless. The usual tactic is to create a base class with common data access functions and then derive them in specific classes for, say, loading Customers.
If object creation is actually the overhead in the entire operation, then you could also look at pooling pre-created objects. However, I highly doubt this is the case.
You might find that a lot of your common data access code could be made into static methods, but a static class for all data access seems like the design is lost somewhere.
Static classes don't have any issues with multi-threaded access per-se, but obviously locks and static or shared state is problematic.
By making the class static, you would have a hard time unit testing it, as then you
would probably have to manage internally the reading of the connection string in a non-clear manner, either by reading it inside the class from a configuration file or requesting it from some class that manages these constants. I'd rather instantiate such a class in a traditional way
var manager = new CompanyInfoManager(string connectionString /*...and possible other dependencies too*/)
and then assign it to a global/public static variable, if that makes sense for the class, ie
//this can be accessed globally
public static CompanyInfoManager = manager;
so now you would not sacrifice any flexibility for your unit tests, since all of the class's dependencies are passed to it through its constructor
I've recently started using an IoC container for the first time, but I'm not educated on the best practices for using it. More specificaly I'm using Unity in a C# .NET project, and I started using it because it came with Prism.
I use the container to resolve the "top level" objects, and they get the correct objects injected based on the container. However, I can't see the best practice clearly when I have an object with children and children's children, and I need some data from the IoC container all the way down, but not in between. How you'd typically organize the use of IoC container?
Initially I'd think that you'd pass the container everywhere it is needed instead of extracting the needed data from the container on top-level and passing this data on. But then again I get problems when I reach objects which take other specific data in addition to the injected interfaces, and I'd prefer not to inject these through properties or init-methods after resolving the object.
I hope this was clear enough, but let's look at a fictional (and slightly stupid..) example.
class Employee
{
private ICommands _commands;
priate List<Customer> _customers = new List<Customer>();
public Employee(ICommands commands)
{
_commands = commands;
}
public void AddCustomer(string customerName)
{
var customer = new Customer(customerName, _commands);
_customers.Add(customer);
}
}
class Customer
{
private string _name;
private ICommands _commands;
priate List<Case> _cases = new List<Case>();
public Customer(string, name, ICommands commands)
{
_name = name;
_commands = commands;
}
public void AddCase()
{
var case = new Case(_commands);
_cases.Add(case);
}
}
class Case {
private ICommands _commands;
public Customer(ICommands commands)
{
_commands = commands;
}
public void TriggerCommands()
{
_command.TriggerSomething();
}
}
So, this example doesn't really make much sense, but the essence is the same of what I need to do. I have some application commands I pass down the line through my ViewModel classes, because some of them need to be able to trigger commands to display something. I also have common storage, etc. which may be needed for some classes but currently are passed through and stored in middle classes. With only commands it's no big deal if you store commands or container, but would one in a typical IoC-usage pass the IoC container instead, and use this for resolving objects down the line? And what about specific data like the customer name? You can't just pass this in on the Resolve(), so you need to inject that afterwards?
Sorry - this was as short as I was able to make it. Won't require answers of the same length ;-) .. Just; what's the best practice of doing stuff like this with IoC containers?
I'm not quite sure that I understand your question. But I don't think you should be passing the container around at all. It's much easier to just create a wrapper class for the container. For example:
public class IoCContainer
{
private static ContainerType = null;
public static ContainerType Instance
{
get
{
if (_container == null)
{
string configFileName = ConfigurationManager.AppSettings[ConfigFileAppSettingName];
_container = new WindsorContainer(new XmlInterpreter(configFileName));
}
return _container;
}
}
}
Now you call this everywhere in your code.
IoCContainer.Instance.Resolve<IAwesomeService>();
Does this help you?
I'm not sure if this answers your question, but I would say that a good way to act on an application using the Unity container (also applicable to other IoC engines I think) is:
Design your classes so that all the
required dependencies are specified
in the constructor. This way you
don't need to explicitly deal with
Unity unless you need to create new
objects.
If you need to create new objects
within your classes, pass the Unity
container itself in the constructor
as well (as a reference to
IUnityContainer), and create all new
object instances by using the Resolve
method. Even for objects that are not
registered and have not dependencies,
the container will give you a proper
instance, and later you can decide to register types that were not previously registered, without changing the client code.
As for passing explicit values to resolved objects, you can specify concrete injection members when you register types (see the InjectionMembers parameter in the RegisterType class).
It seems that you need to declare factories for your entities. Resolve factories via constructor injection and pass data values via Create method. All other dependencies must be resolved via factory's constructor.
See this answer.
I'd define a static class IoC, that can be initialized with a particular container and implement methods like Resolve, Resolve(...), which in turn delegate the actual work to the container instance (you'll store this instance in a field or property). This way you don't have to pass anything around, just use
IoC.Resolve<SomeType>();
anywhere in your code.
Regarding the specific data: some containers will take a parameter and resolve depending on this parameter (Autofac has this kind of feature). Or you can always create a factory class that will have a method that accepts a set of parameters (like customer name) and returns a corresponding object instance.
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.