I am wondering how to tell NHibernate to resolve dependencies on my POCO domain objects.
I figured out that methods like CalculateOrderTax should be in the Domain object because they encode domain specific business rules. But once I have two of those I am violating SRP.
It would be no problem to extract those methods to Strategy classes, but I wonder how to make NHibernate load those.
It doesn't seem like a good solution to loop through a list of objects in the repository to do get/set based Dependecy injection before handing the object off to the higher layers.
I am also using Castle Windsor for my Depency injection right now.
I've been using interceptors for similar tasks:
An interceptor that modifies loaded entities:
public class MyInterceptor : EmptyInterceptor
{
public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
{
return InjectDependencies(entity as MyEntity);
}
}
Associate it with a session:
nhSessionFactory.OpenSession(myInterceptor);
I've also read somewhere that there would be better support for custom constructor injection in the upcoming 2.1 release but I can't seem to find the reference right now.
As no-one seems to be able to answer your question at the moment I thought I'd suggest restructuring your code to remove the need for the Order to calculate it's own tax.
You could delegate it to a OrderTaxService which takes an Order object and returns an OrderValue object or something along those lines.
This will keep the logic in your domain but remove the need to attach it to your Order objects.
I agree with Garry that you should remove service dependencies from your domain objects as much as possible. Sometimes it makes sense, such as encryption/decryption. In that case you can hide it in the infrastructure using interception or IUserType. I think the latter is favorable when you can use it. This article shows in detail how to do it. I am doing this and it works quite fine.
Related
I'm trying to create a Generic repository which accepts 2 generic types e.g.
public class EfRepository<T, TS> : IAsyncRepository<T,TS> where T : BaseEntity
where TS : DbContext
{
..........
}
and in my startup.cs I have the usual mapping:
services.AddScoped<DbContext, ConfigDbContext>();
How can I now add another mapping to DbContext? I have tried adding another mapping between DbContext and another Context i created but It only ever uses the first mapping.
I have multiple databases I need to consume and would ideally like to have a DbContext for each one but i can't see a way of having multiple DI mappings.
In my EfRepository class the following code exceptions when I add an extra DbContext to my code and use it:
protected readonly DbContext _dbContext;
public EfRepository(DbContext dbContext)
{
this._dbContext = (TS)dbContext;
}
The exception is Unable to Convert from Type1 to Type2 and I know this is because the DbContext is bound to Type1 in my startup.cs.
How can I (if possible) use multiple DbContext's in a generic fashion?
That's not how you register DbContext, which is the source of your problem. The correct method is:
services.AddDbContext<ConfigDbContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("Foo")));
Done correctly, adding another is exactly the same:
services.AddDbContext<SomeOtherContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("OtherConnectionString")));
Then, which one gets pulled depends on which one you inject, which yes, does mean that you need to specify the actual type you want to inject, not DbContext generically. However, that can be done only one the derived class. In other words, you can keep the code you have (though you should not cast the context) and simply do:
public class FooRepository : EFRepository<Foo, ConfigDbContext>
{
public FooRepository(ConfigDbContext context)
: base(context) {}
}
You can leave it upcast to DbContext, as you don't need the actual type to do EF things. To get at the DbSets, you can use the generic Set<T>:
var foos = _dbContext.Set<Foo>();
And now, with all that said, throw it all out. It's completely unacceptable to use the repository pattern with an ORM like EF. EF already implements the repository and unit of work patterns. The DbContext is your unit of work, and each DbSet is a repository. Adding an extra layer on top of that does nothing but add maintenance concerns and extra entropy to your code, and frankly, creating a repository/unit of work that plays nice with EF, is so trying as to be impossible, so more often than not, you're just going to hamstring EF, making it less efficient and harder to use.
Using an ORM like EF is choosing to use a third-party DAL. That is all. There's no need to create your own DAL at that point, because you've outsourced it. I'm not sure why so many people get hung up on this. When was the last time you created your own routing framework or your own templated view preprocessor. Never. You just third party libraries for that (the framework), so why is it a problem to use a third party library for your DAL as well?
Then, you make ask well what about abstracting the EF dependency. Well, first, if you're thinking you might switch ORMs some day down the road, you won't. It just never happens. You'll sooner rewrite the whole app from the ground up. Second, the repository pattern doesn't even achieve this. You still have an EF dependency that bubbles all the way up to the front-line app. There's no way around that.
For true abstraction, you can use something like microservices architecture. Other than that, just embrace the dependency or don't use it at all, and really create your own DAL.
How to make entities lazy load its relationships?
For example: Post and Comment models, where a Post can have 0 or more Comments. How to make the getComments() method on Post entity lazy load its Comments?
My first think, is to have an CommentRepository injected into my Post entity, how is this bad? Since Entities and Repositories are part of may domain, why can't they have a two way knowledge about each other?
Thank you
UPDATE
I know there are many excellent industry standard ORMs that perform lazy loading for the main languages out there, but I don't want to rely on its magics. I'm looking for a ORM/DBAL agnostic solution to make sure of the application's low coupling.
Aggregates represent a consistency boundary so there should never be a need to lazy-load related data as the aggregate as a whole should always be consistent. All objects that belong to an aggregate have no need to exist on their own. If you do have an object that has it's own life-cycle then it needs to be removed from the aggregate.
When you do find that you need to do this you may want to rethink your design. It may be that you are using your object model to query. You should rather have a light-weight query model that can perform this function.
Injecting repositories or services into entities is generally not the best idea. A double-dispatch mechanism should be preferred.
But in your case I would still try to not lazy-load.
Consider using a proxy that subclasses Post, overrides the getComments() method. Inject the proxy with the CommentRepository and access it in the overridden getComment() method.
This is how an ORM would typically do it. It keeps your domain classes clean as only the proxy is dependent on a data access mechanism.
At first, you should separate domain concept from details of realization. Agreagate pattern is about how to organize your domain and lazy-loading is an implementation detail.
Also, I disagree with #Eben Roux about inconsistency of agreates. Lazy loading contradicts nothing in my opinion. I express why.
Lazy loading itself
To understand how lazy loading can be implemented you may refer to Martin Fowler's PoEAAA pattern 'Lazy loading'. For me, proxy pattern is the best solution.
Also, it's important that most nowadays ORMs supports lazy loading, BUT for data model (not domain model).
It is a good practice to separate data model and domain model and use repostiories to hide this transformation:
Separated domain and data models
In this case objects of domain model are constructed inside repositories those hide ORM context. Required data object and all associations are loaded by ORM, than transformation to domain model is performed, and finally, constructed domain object returned.
The question is how to load some associations not during creation of domain object, but during it's lifetime. You can use Repoisotry inside entity and I see nothing wrong with it. It will looks like:
public class Post {
private ICommentsRepository _commentsRepository;
private IList<Comments> _comments;
//necessary to perform lazy loading (repository always wroks with ids)
private IList<int> _commentIds;
//realize lazy loading
...
}
there are problems:
Your model now becomes not clear. It contains 'techincal' information like _commentIds.
As soon as you want to define ICommentsRepository you claim the Comment to be aggregate root. If we introduce agregate pattern into domain model, repositories should be creaed just for agregate roots. Thus it means that Comment and Post are different agregate roots. And possible that it is not what you want.
There is better solution:
public interface ICommentList {
...
}
public class CommentList : ICommentList {
...
}
public class CommentListProxy : ICommentList {
private CommentList _realCommentList;
private IList<int> _commentIds;
//realize lazy loading here using ORMs capabilities!
//don't use repository here!
}
public class Post {
private ICommentList _commentList;
...
}
Post repository will initaize _commentList field with proxy object. Also, it is necessary to say:
CommentListProxy relates to data model layer, not to domain model. It uses ORMs capabilities to implement lazy loading
and thus doesn't use repositories, and thus you may consider CommentList as a part of the Post agregate.
The only possible disadvantage of this approach is in implicit database querying when operating with domain objects. This must be clear for users of the Post class.
Smart ORMs
Finally there are kind of ORMs which allows you to use same model for both domain and data. It realizes lazy-loading for domain model in a same way as for data model. Take a look at DataObjects.Net. For some cases it is a good solution.
I'm currently trying out a few different ways of implementing repositories in the project I'm working on, and currently have a single repository with generic methods on it something like this:
public interface IRepository
{
T GetSingle<T>(IQueryBase<T> query) where T : BaseEntity;
IQueryable<T> GetList<T>(IQueryBase<T> query) where T : BaseEntity;
T Get<T>(int id) where T : BaseEntity;
int Save<T>(T entity) where T : BaseEntity;
void DeleteSingle<T>(IQueryBase<T> query) where T : BaseEntity;
void DeleteList<T>(IQueryBase<T> query) where T : BaseEntity;
}
That way I can just inject a single repository into a class and use it to get whatever I need.
(by the way, I'm using Fluent NHibernate as my ORM, with a session-per-web-request pattern, and injecting my repository using Structuremap)
This seems to work for me - the methods I've defined on this repository do everything I need. But in all my web searching, I haven't found other people using this approach, which makes me think I'm missing something ... Is this going to cause me problems as I grow my application?
I read a lot of people talking about having a repository per root entity - but if I identify root entities with some interface and restrict the generic methods to only allow classes implementing that interface, then aren't I achieving the same thing?
thanks in advance for any offerings.
I'm currently using a mix of both generic repositories (IRepository<T>) and custom (ICustomRepository). I do not expose IQueryable or IQueryOver from my repositories though.
Also I am only using my repositories as a query interface. I do all of my saving, updating, deleting through the Session (unit of work) object that I'm injecting into my repository. This allows me to do transactions across different repositories.
I've found that I definitely cannot do everything from a generic repository but they are definitely useful in a number of cases.
To answer your question though I do not think it's a bad idea to have a single generic repository if you can get by with it. In my implementation this would not work but if it works for you then that's great. I think it comes down to what works best for you. I don't think you will ever find a solution out there that works perfectly for your situation. I've found hybrid solutions work best for me.
I've done something similar in my projects. One drawback is that you'll have to be careful you don't create a select n+1 bug. I got around it by passing a separate list of properties to eagerly fetch.
The main argument you'll hear against wrapping your ORM like this is that it's a leaky abstraction. You'll still have to code around some the "gotchas" like select n+1 and you don't get to take full advantage of things like NH's caching support (at least not without extra code).
Here's a good thread on the pros and cons of this approach on Ayende's blog. He's more or less opposed to the pattern, but there are a few counter arguments too.
I've implemented such kind of repository for NHibernate. You can see example here.
In that implementation you are able to do eager loading and fetching. The pitfall is that with NH you will often need to be able to use QueryOver or Criteria API to access data (unfortunately LINQ provider is still far from being perfect). And with such an abstraction it could be a problem leading to leaky abstraction.
I have actually moved away from repository pattern and creating a unit of work interfaces - I find it limiting.
Unless you anticipate a change in the datastore i.e. going from DB to textfile or XML - which has never been the case for me, you are best off using ISession. You are trying to abstract your data access and this is exactly what NHibernate does. Using repository limits really cool features like Fetch(), FetchMany() futures etc. ISession is your unit of work.
Embrace NHibernate and use the ISession directly!
I've used this approach successfully on a few projects. It gets burdensome passing in many IRepository<T> to my Service layers for each BaseEntity, but it works. One thing I would change is put the where T : on the interface rather than the methods
public interface IRepository<T> where T : BaseEntity
I've noticed Repository is usually implemented in either of the following ways:
Method 1
void Add(object obj);
void Remove(object obj);
object GetBy(int id);
Method 2
void Save(object obj); // Used both for Insert and Update scenarios
void Remove(object obj);
object GetBy(int id);
Method 1 has collection semantics (which is how repositories are defined). We can get an object from a repository and modify it. But we don't tell the collection to update it. Implementing a repository this way requires another mechanism for persisting the changes made to an in-memory object. As far as I know, this is done using Unit of Work. However, some argue that UoW is only required when you need transaction control in your system.
Method 2 eliminates the need to have UoW. You can call the Save() method and it determines if the object is new and should be Inserted or is modified and should be Updated. It then uses the data mappers to persist the changes to the database. Whilst this makes life much easier, a repository modeled doesn't have collection semantics. This model has DAO semantics.
I'm really confused about this. If repositories mimic in-memory collection of objects, then we should model them according to Method 1.
What are your thoughts on this?
Mosh
I personally have no issue with the Unit of Work pattern being a part of the solution. Obviously, you only need it for the CUD in CRUD. The fact that you are implementing a UoW pattern, though, does nothing more than dictate that you have a set of operations that need to go as a batch. That is slightly different than saying it needs to be a part of a transaction. If you abstract your repositories well enough, your UoW implementation can be agnostic to the backing mechanism that you are using - whether it is database, XML, etc.
As to the specific question, I think the difference between method one and method two are trivial, if for no other reason than most instances of method two contain a check to see if the identifier is set. If set, treat as update, otherwise, treat as insert. This logic is often built into the repository and is more for simplification of the exposed interface, in my opinion. The repository's purpose is to broker objects between a consumer and a data source and to remove having to have knowledge of the data source directly. I go with method two, because I trust the simple logic of detecting an identifier than having to rely on tracking object states all over the application.
The fact that the terminology for repository usage is so similar to both data access and object collections lend to the confusion. I just treat them as their own first class citizen and do what is best for the domain. ;-)
Maybe you want to have:
T Persist(T entityToPersist);
void Remove(T entityToRemove);
"Persist" being the same as "Save Or Update" or "Add Or Update" - ie. the Repo encapsulates creating new identities (the db may do this) but always returns the new instance with the identity reference.
I dig a lot of things about the DDD approach (Ubiquitous language, Aggregates, Repositories, etc.) and I think that, contrary to what I read a lot, entities should have behavior rather then being agnostic. All examples I see tend to present entities with virtual automatic properties and an empty constructor (protected or worst, public) and that's it. I consider this kind of objects more like DTOs then entities.
I'm in the process of creating a framework with its specific API and I don't want to be tied to an ORM. So I built the domain first (without thinking of persistence) and now I would like to use NHibernate as persistence tool so I added a new project to my current solution to help ensure that my model isn't altered to support NHibernate. This project should be an implementation of the abstract repositories that live inside my domain. And now the difficulties arise.
Since it is my first time with NHibernate (I'm also trying Fluent Nhibernate but it seems even more restricting) I would like to know :
Is it possible to use NHibernate without altering a DDD model that is part of a framework
The things (constraints) that are necessary for NHibernate to work as expected and efficiently (virtual properties, empty constructors, etc.) I think this list would be helpful to a lot of people who are starting to learn NHibernate.
Please keep in mind that I'm building a framework so the Open/Closed Principle is very important for me.
P.S.: Sorry if my english is not good, I'm from Montreal and I speak french.
Edit 1: Here is one problem I have with NHibernate now - How to map Type with Nhibernate (and Fluent NHibernate)
For NHibernate:
All mapped classes require a default (no-arguments) constructor. The default constructor does not have to be public (it can be private so that it is not a part of the API), but it must exist. This is because NHibernate must be able to create an instance of the mapped class without passing any arguments. (There are workarounds, but don't do that.)
All mapped properties for which lazy-loading will be required must be marked virtual. This includes all reference properties and all collection properties. This is because NHibernate must be able to generate a proxy class deriving the mapped class and overriding the mapped property.
All mapped collection properties should use an interface as the property type. For example, use IList<T> rather than List<T>. This is because the collections types in the .NET Framework tend to be sealed, and NHibernate must be able to replace a default instance of the collection type with its own instance of the collection type, and NHibernate has its own internal implementations of the collection types.
For NHibernate, prefer Iesi.Collections.Generic.ISet<T> to System.Collections.Generic.IList<T>, unless you are sure that what you want is actually a list rather than a set. This requires being conversant in the theoretical definitions of list and set and in what your domain model requires. Use a list when you know that the elements must be in some specific order.
Also note that it's typically not easy to swap object-relational mapping frameworks, and in many cases it is impossible, when you have anything beyond a trivial domain model.
The short answer to your question is that it is not possible, but if don't need lazy loading the required alterations are trivial.
No matter what, you will have add default constructors to classes that do not already have them. If you are willing to forgo lazy-loading, those default constructors can be private, and you don't have to make any other changes to your domain model to use NHibernate.
That's awfully close to persistence ignorance.
Having said that, if you want lazy-loading, you'll need to make several changes (outlined in other answers to this question) so that NHibernate can create proxies of your aggregated entities. I'm personally still trying to decide whether lazy-loading is an enabling technology for DDD or if it's a premature optimization that requires too many intrusive changes to my POCOs. I'm leaning toward the former, though I really wish NHibernate could be configured to use a specific constructors.
You might also take a look at Davy Brion's blog (I particularly liked Implementing A Value Object With NHibernate), which is really illuminating if you're interested in domain-driven-design and avoiding anemic domain models.
In my experience, the only thing that NHibernate requires of a domain is virtual properties and methods and a default no-argument constructor, which as Jeff mentioned, can be marked private or protected if need be. That's it. NHibernate is my OR/M of choice, and I find the entire NHibernate stack (NHibernate, NHibernate Validator, Fluent NHibernate, LINQ to NHibernate) to be the most compelling framework for persisting POCO domains.
A few things you can do with NHibernate:
Decorate your domain model with NHV attributes. These constaints allow you to do three things: validate your objects, ensure that invalid entities are not persisted via NHibernate, and help autogenerate your schema when using using NHibernate's SchemaExport or SchemaUpdate tools.
Map your domain model to your persistent storage using Fluent NHibernate. The main advantage, for me, in using FNH is the ability to auto map your entities based on conventions that you set. Additonally, you can override these automappings where necessary, manually write class maps to take full control of the mappings, and use the xml hbm files if you need to.
Once you buy into using NH, you can easily use the SchemaExport or SchemaUpdate tools to create and execute DDL against your database, allowing you to automatically migrate domain changes to your database when initilizing the NH session factory. This allows you to forget about the database, for all intents and purposes, and concentrate instead on your domain. Note, this may not be useful or ideal in many circumstances, but for quick, local development of domain-centric apps, I find it convenient.
Additionally, I like using generic repositories to handle CRUD scenarios. For example, I usually have an IRepository that defines methods for getting all entites as an IQueryable, a single entity by id, for saving an entity, and for deleting an entity. For anything else, NH offers a rich set of querying mechanisms -- you can use LINQ to NHibernate, HQL, Criteria queries, and straight SQL if need be.
Th only compromise you have to make is using NHV attributes in your domain. This is not a deal breaker for me, since NHV is a stand-alone framework which adds additional capabilities if you choose to use NHibernate.
I have built a few apps using NH, and each has a persistence ignorant domain with all persistence concerns separated into its own assembly. That means one assembly for your domain, and another for your fluent mappings, session management, and validation integration. It's very nice and clean and does the job well.
By the way: your English is pretty darn good, I wish my French was up to par ;-).
Just to put my two bits in, I struggled with the same thing once but I overcame this by:
Adding protected default constructor to every entity.
Making Id virtual
Let's take for example upvote and downvote for Vote entity on my experiment website:
http://chucknorrisfacts.co.uk/ (NHibernate + MySQL with Mono)
public class Vote : Entity
{
private User _user;
private Fact _fact;
// true: upvote, false: downvote
private bool _isupvoted;
// for nHibernate
protected Vote() { }
public Vote(User user, Fact fact, bool is_upvoted)
{
Validator.NotNull(user, "user is required.");
Validator.NotNull(fact, "fact is required.");
_fact= fact;
_user = user;
_isupvoted = is_upvoted;
}
public User User
{
get { return _user; }
}
public Fact Fact
{
get { return _fact; }
}
public bool Isupvoted
{
get { return _isupvoted; }
}
}
This class inherits from Entity where we stick all the minimum necessary for Nhibernate.
public abstract class Entity
{
protected int _id;
public virtual int Id { get {return _id;} }
}
and Fluent mapping where you Reveal the private property.
public class VoteMap : ClassMap<Vote>
{
public VoteMap()
{
DynamicUpdate();
Table("vote");
Id(x => x.Id).Column("id");
Map(Reveal.Member<Vote>("_isupvoted")).Column("vote_up_down");
References(x => x.Fact).Column("fact_id").Not.Nullable();
References(x => x.User).Column("user_id").Not.Nullable();
}
}
You could probably place protected default constructor in Entity class and configure nHibernate to use it instead but I didn't look into it yet.