Clean Architecture Question:
I have an entity A that have a collection of entity B Inside it
Like this:
// Entity
class A {
id,
bArr: B[]
}
// Entity B
class B {
// Some Props
}
How do I manage the bArr Collection?
Do I manage it inside A Repository?
Create another Repository for managing the collection like First Class Collections?
Another option?
A simple solution might be to have a single repository for both entities. I recommend reading about "Unit of Work" pattern.
Related
Consider the following scenario in Laravel 4.1
there is a Set model that may have many items (sorted by precedence, but this can be put aside for now)
each of these items can be of a different "kind" (think of a bag (the Set) that contains keys,wallet,cigs...)
Ideally I would like to achieve the following:
have a simplified, eager-loadable relationship between a Set and its items (explained better below)
keep the item models DRY (ideally each item extends an abstract class with basic boilerplate code)
To better illustrate what I have in mind:
class Set extends Eloquent {
// ...
public function items() {
// provides a "transparent" method to access ALL of its items ... no matter what class
}
}
and
class SubItemOne extends Item { // ... }
class SubItemTwo extends Item { // ... }
abstract class Item extends Eloquent {
public function set() {
return $this->belongsTo('Set');
}
}
because at its core each sub-class shares a lot in common with the others (think of: they can all be moved around in the set, or they can be attached an image etc. ... all of which could be defined within the abstract Item class).
Essentially, I want to be able to access all of the items belonging to my Set in situations like
Set::with('items')->find(1);
but I'm really unsure about what kind of relationship to use for the 'inverse'.
Things I've considered so far:
take out the subclassed models and just keep one Item model with a "item_kind" flag to identify its type. Have each item define a relationship to another class based on this flag... (already sounds butt-ugly to me)
polymorphic relations (including the new N-2-N introduced in L 4.1) although they don't really seem to be thought for this specific scenario: especially N2N still doesn't solve the problem of accessing ALL the items via one simple relation
ditch the eager-loadable relation and write a custom "get_items()" method that would access the individual relationships (as in ->subitemones(), ->subitemtwos() etc ) but this seems like a rather dumb way to solve this problem (i really would like to be able to access the relationship within the query builder)
I'm kinda stuck here but I can't believe I'm the only one facing this situation... I'm really hoping for a "best practice" kind of suggestion here!
You could consinder maping your class hierarcy to DB hierarcy. There are many ways to represent inheritance in your DB schema.
Considering your scenario you can have the following tables:
Set: This entity maps your parent class and stores all common information of a Set Item (eg Position etc)
SubItemOne: Extends the "set" entity, and stores only the additional information specific to this type.
SubitemTwo... etc
SubItemXXX have a 1:1 relationship with the Set entity. All you have to do is a simple JOIN to merge SubItemXXX and Set
You can read more at: How can you represent inheritance in a database?
Well, in this post, I get to the conclusion that is better to work with services in per call mode, because it's more efficient. This makes me to have data context with a short life, the life of the method that I call.
In this example, I see how to modify data of a list of elements, only is needed to set the state of the entity to modified.
However, how could I do with one operation, modifies and updates, for example?
One case can be this. I have books and authors, and the client application have a view with two datagrids, one for authors and other for books. The user can add authors and modify their information in the first datagrid and do the same with the books in the second datagrid. Also can assign books to their authors.
I have the POCO classes, so I have a author class with a property that is a list of books. Well, I can add books to this list, and then when I call the service method updateAuthors, I only need to use the class of author as parameter, EF knows what to do with the books. It is not needed to pass the book too.
But what happens when in the list of books there are new books and also books that exists but its information is modified?
In the example of the post that I mention in the beginning it says how to do it when all the entity are modify, but if I want to add new registers, I need to set the state to add. So if there is mixed entities, how can I do it? does it exist any pattern or a some way to do this? I have to set the state of all the books? I can know the state of the books, because I use an autonumeric as ID, so if the ID is 0 is a new register, in other case is a modification.
Thanks.
Daimroc.
EDIT: Perhaps I don't be very clear in my question. What I want to know is how I can save the changes of many entities at once. For example, I have the Authors, Books and Custormers. I Add, modify and delete information of many of them. In my WCF client I have method to save changes of Authors, other method to save changes of books and other method to save changes of Customers.
How my service is per call, I need to make three calls, one for each type of entities, and this are independents. However, if I use directly entity framework, I can do many changes to many type of entities and I only need to call savechanges once, it make all the work. How can I do the same with WCF and POCO entities?
I am reading about self tracking entities, buy I have the same problem, I can use Applychanges(entity) but if I am not wrong, it applies changes only to one entity. do I need to call N times if I did changes to many entities?
Thanks.
Not sure if this will answer your question, but here is my suggestion:
Manage the state on your POCO entities by using flags (IsNew, IsDirty, IsDeleted);
When you pass the POCO entities to the object context, use the ObjectStateManager to change the attached entity state;
Recursively loop through the list of children entities and apply the same approach.
EDIT:
The following code is the AuthorStateManager class:
public partial class AuthorStateManager : IStateManager<Author, Context>
{
private IStateManager<Book, Context> _BookStateManager = new BookStateManager();
public void ChangeState(Author m, Context ctx)
{
if (m == null) return;
ctx.Authors.Attach(m);
if (m.IsDeleted)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Deleted);
}
else
{
if (m.IsNew)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Added);
}
else
{
if (m.IsDirty)
{
ctx.ObjectStateManager.ChangeObjectState(m, System.Data.EntityState.Modified);
}
}
}
SetRelationsState(m, ctx);
}
private void SetRelationsState(Author m, Context ctx)
{
foreach (Book varBook in m.Books)
{
_BookStateManager.ChangeState(varBook, ctx);
}
}
}
where Authors is the ObjectSet, m is a POCO entity of type Author, ctx is the object context, and SetRelationsState is the method that loops through all the children state managers to update their state.
After changing the state, in my repository object I call ctx.SaveChanges(). This is the Update method in AuthorRepository class:
public Author Update(Author m, bool commit)
{
_AuthorStateManager.ChangeState(m, _ctx);
if (commit)
{
_ctx.SaveChanges();
}
return m;
}
_BookStateManager is a private member of BookStateManager type which modifies the Book state in its own ChangeState() method.
I suggest you make the State Manager classes implement an interface called IStateManager, which has the ChangeState() method.
It seems a bit convoluted, but it gets easier if you generate code for these classes.
If you want to perform multiple actions in a single service call, then the action to take need to move from being a method call to an object. For example, you might have a InsertCustomerAction class which has a Customer instance tied to it. All of these actions would have a base class (Action) and your WCF method would take in a collection of Action instances.
I might be in the process of trying something (bad), just to see what I come up with.
For starters, we built an application in a DDD fashion - our opinion. The design is "classic" DDD, meaning we have repositories for aggregate roots.
We do have a base Entity where we override Equals, GetHashCode, etc. Our entities are only logical deleted ie we use an IsActive field.
As ORM we use NHibernate >3.
The thing I'd like to try: I'd like to be able to remove an entity from a list inside an aggregate root with a syntax like this:
aggregateRoot.Entities.Remove(entity);
In the persistence layer, the default NHibernate behaviour for "entity" ("entity" has a back-reference to "aggregateRoot") is to update the "entity" with a NULL on "aggregateRoot" column. What we actually want to do is this:
repository.Delete(entity);
which just marks "entity" as being inactive while "entity" remains in the "aggregateRoot" 's collection.
Most probably my idea is just plain stupid (as I said once again), but I'd like to try to teach NHibernate that "entity" should not be updated with a null reference to "aggregateRoot", just make it inactive. Why? Because I want to use the repository explicitly where it is required.
What I am asking is if this is achievable through NHibernate Interceptors; I haven't tried them yet and I want to prioritize my backlog.
Why don't you just implement a Delete method on your entities? You may hide it behind a core interface. The advantage is a completely persistence ignorant implementation which doesn't require NH to exist.
class Root
{
// ...
public void Remove(Entity entity)
{
IRootManaged managed = (IRootManaged)entity
managed.Delete();
}
}
class Entity : IRootManaged
{
// ...
public bool IsDeleted { get; private set; }
public void IRootManaged.Delete()
{
this.IsDeleted = true;
}
}
Sorry if I missed the point here ...
In a classic DDD, aggregateRoot.Entities.Remove(entity); is a bad practice anyway. You'd better create a method on the root entity, say RemoveEntity(Entity e), and there you will encapsulate the Delete mechanism in which you will set the Entity.IsActive to false.
Take a look at this: http://ayende.com/blog/4157/avoid-soft-deletes
Im pretty new to nhibernate so this may be quite straightforward but i havent found an answer on the web yet.
Lets say i have a Parent class and a Child class. The Parent Class can have many Child classes associated with it. Now when i try to load a specific Parent nhibernate also populates its Child collection for me. There are situations where I want to just return a Parent class without a Child collection.
I know i can turn on Lazy loading but that wont work as im serializing the Parent to XML. The XML serialiser cannot work with the nhibernate PersistanceBag that contains the Child collection.
So is there a way to define a Parent class, lets say ParentView which works on the same table but only contains the Parent properties and not all its children and grandchildren?
Define a class ParentView that contains the columns you need to retrieve. Make sure this class has one parameterless constructor.
ISession session = NHibernateHelper.Session;
ISQLQuery query = session.CreateSQLQuery("select Parent_ID, Name form Parent where Parent_ID = :parentID");
query.SetInt32("parentID", parentID);
IList<ParentView> parentView = query.SetResultTransformer(Transformers.AliasToBean<ParentView>()).List<ParentView>();
return parentView;
An alternative to creating a view class and associated query as suggested by sh_kamalh (which I would consider if I were you). If the problem is related to the bag mapping structure specifically then you might have a couple of easier solutions:
Option 1
Revisit the bag mapping - Maybe simple selecting a different strategy will fix the issue. I have answered a question on the different collection mappings before List vs Set vs Bag in NHibernate personally I find that I use the Set strategy a lot. To map a different strategy in Fluent NHibernate use the following as a guide in your override.
mapping.HasMany<Child>(x => x.Children).ToSet();
or
mapping.HasMany<Child>(x => x.Children).ToList();
Option 2
Not particularly related to NHibernate but if you are using the default xml serializer you might be able to tell the xml serializer to simply ignore that property and leave the bag mapping in place.
[System.Xml.Serialization.XmlIgnore]
public IEnumerable<Child> Children { get; internal set; }
Is it a violation of the Persistance igorance to inject a repository interface into a Entity object Like this. By not using a interface I clearly see a problem but when using a interface is there really a problem? Is the code below a good or bad pattern and why?
public class Contact
{
private readonly IAddressRepository _addressRepository;
public Contact(IAddressRepository addressRepository)
{
_addressRepository = addressRepository;
}
private IEnumerable<Address> _addressBook;
public IEnumerable<Address> AddressBook
{
get
{
if(_addressBook == null)
{
_addressBook = _addressRepository.GetAddresses(this.Id);
}
return _addressBook;
}
}
}
It's not exactly a good idea, but it may be ok for some limited scenarios. I'm a little confused by your model, as I have a hard time believing that Address is your aggregate root, and therefore it wouldn't be ordinary to have a full-blown address repository. Based on your example, you probably are actually using a table data gateway or dao rather than a respository.
I prefer to use a data mapper to solve this problem (an ORM or similar solution). Basically, I would take advantage of my ORM to treat address-book as a lazy loaded property of the aggregate root, "Contact". This has the advantage that your changes can be saved as long as the entity is bound to a session.
If I weren't using an ORM, I'd still prefer that the concrete Contact repository implementation set the property of the AddressBook backing store (list, or whatever). I might have the repository set that enumeration to a proxy object that does know about the other data store, and loads it on demand.
You can inject the load function from outside. The new Lazy<T> type in .NET 4.0 comes in handy for that:
public Contact(Lazy<IEnumerable<Address>> addressBook)
{
_addressBook = addressBook;
}
private Lazy<IEnumerable<Address>> _addressBook;
public IEnumerable<Address> AddressBook
{
get { return this._addressBook.Value; }
}
Also note that IEnumerable<T>s might be intrinsically lazy anyhow when you get them from a query provider. But for any other type you can use the Lazy<T>.
Normally when you follow DDD you always operate with the whole aggregate. The repository always returns you a fully loaded aggregate root.
It doesn't make much sense (in DDD at least) to write code as in your example. A Contact aggregate will always contain all the addresses (if it needs them for its behavior, which I doubt to be honest).
So typically ContactRepository supposes to construct you the whole Contact aggregate where Address is an entity or, most likely, a value object inside this aggregate.
Because Address is an entity/value object that belongs to (and therefore managed by) Contact aggregate it will not have its own repository as you are not suppose to manage entities that belong to an aggregate outside this aggregate.
Resume: always load the whole Contact and call its behavior method to do something with its state.
Since its been 2 years since I asked the question and the question somewhat misunderstood I will try to answer it myself.
Rephrased question:
"Should Business entity classes be fully persistance ignorant?"
I think entity classes should be fully persistance ignorant, because you will instanciate them many places in your code base so it will quickly become messy to always have to inject the Repository class into the entity constructor, neither does it look very clean. This becomes even more evident if you are in need of injecting several repositories. Therefore I always use a separate handler/service class to do the persistance jobs for the entities. These classes are instanciated far less frequently and you usually have more control over where and when this happens. Entity classes are kept as lightweight as possible.
I now always have 1 Repository pr aggregate root and if I have need for some extra business logic when entities are fetched from repositories I usually create 1 ServiceClass for the aggregate root.
By taking a tweaked example of the code in the question as it was a bad example I would do it like this now:
Instead of:
public class Contact
{
private readonly IContactRepository _contactRepository;
public Contact(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
public void Save()
{
_contactRepository.Save(this);
}
}
I do it like this:
public class Contact
{
}
public class ContactService
{
private readonly IContactRepository _contactRepository;
public ContactService(IContactRepository contactRepository)
{
_contactRepository = contactRepository;
}
public void Save(Contact contact)
{
_contactRepository.Save(contact);
}
}