I have a Generic IRepository<T>
which gets implemented under Infrastructure.NHibernate
Using Simple Injector
to inject the implementation into the interface. IRepository<T>
lives in my Domain
so that the domain objects can use the repository which was injected.
I have a User``AggregateRoot
which holds some detail about the user in the application database, Id
, Firstname
, Lastname
. I know not to care about persistence, but this at stage we are talking about how these objects are persisted.
In my Web.UI
(ASP.Net MVC 5) I have a screen where I can update the user details, Firstname
, Lastname
, Email
, Address
. Id is stored but can't be updated.
When I update the User
details, I use the IRepository<User>
to update Firstname
and Lastname
.
Problem: I need to update the Firstname
, Lastname
, Email
, Address
in our OpenLdap
server too.
I have an Infrastructure.Ldap
project where all the Ldap implementations etc sits. (repositories, services, entities, helpers, converters).
What is the best approach to update the LDap server?
Do I create another ISomeRepository
Interface in the Domain
which Infrastructure.Ldap
implements? This will mean I need to add additional attributes to the User
and just override the ORM Mapping to ignore additional attributes. I then use the IRepository
, followed by ISomeRepository
to update the user in both databases.
Or
Web.UI is already an infrastructure concern, so I just reference the Infrastructure.Ldap
project and talk to the ldap repository directly which will work with a LDapUser
object. This will let me update the User on Ldap separately.
I'm very confused, business rules are that we need to update user details. I assume from a DDD perspective, all the details that needs to be updated needs to live in the domain. how do I persist this User
on 2 different data stores?
Is one of my options above valid and pass good practice, or is there perhaps a different solution? The business requires there to be the 2 different data stores, therefore I need to make this work.
Id
, Firstname
, Lastname
- this is stored in the application database in case Ldap goes down and will be used for auditing purposes later on.
Id
, Firstname
, Lastname
, Email
, Address
- this is stored in the OpenLdap
server part of user administration.
Can someone please point me into the right direction please. Its really hard to think of this case strictly from a DDD perspective due to he constraints of where persistence needs to happen. If it was all on the application database, it would have been easy.
You can use Composite
design pattern with your repositories :
public IRepository<T>
{
void Save(T entity);
}
public class CompositeRepository<T> : IRepository<T>
{
private readonly IEnumerable<IRepository<T>> repositories;
public CompositeRepository(IEnumerable<IRepository<T>> repositories)
{
if(repositories == null)
{
throw new ArgumentNullException("repositories");
}
this.repository = repositories;
}
public void Save(T entity)
{
foreach(var repository in repositories)
{
repository.Save(entity);
}
}
}
Let's assume that there exists SqlUserRepository
and LdapUserRepository
and both implements IRepository<User>
. Then you can register CompositeUserRepository
using container:
container.RegisterCollection<IRepository<User>>(new[] { typeof(SqlUserRepository),
typeof(LdapUserRepository) });
container.Register<IRepository<User>, CompositeRepository<User>>();
Thanks to that your services further use IRepository<User>
and they don't have to change when you add persisting User
to LDAP
. We also achieved nice side effect of that way solving this problem - Single Responsibility
principle in context of repositories.