I have some more questions here.

As I've mentioned previously, I'm from Python/Django background. In Django, 
there is very clear distinction between the Model itself and the model's 
Manager.

The Model is a set of data (properties, which are persisted in the DB) and 
the methods which *work on the instance *of this (single, exact) Model. 
Given the example *Invoice* Model, the correct method to place in this 
Model would be CalculateFinalPrice() which updates the final_price field in 
the instance of the model it's being called on.

The Manager on the other hand is responsible for creating and querying 
objects (and also for batch operations, but let's skip it here). That is, 
if there's some querying criteria which is commonly used - one can 
implement method like *BlogPostManager.PublishedOnly() *which adds some 
*is_published 
= 1* to the query criteria.

Now, I'm not sure if I use "Repository" term correctly, so - for the 
clarification - I understand it as something similar to the above 
description of Manager. 
Thus I understand the Repository is a good place for querying business 
logic methods, but not for methods which operate/modify on the single 
instance of given object. Was I wrong all the time?

As you can see now, the place for a method which works on the single 
instance of business object is - for me - obviously the Domain Model 
itself. 
This was perfectly fine, until I realized for some of these methods I need 
to query some other (unrelated, in terms of DB relations) objects - get 
current PricingPlan etc.
Refering to Django again, it is not a problem there, since each Model is 
aware of it's Manager instance (via a static property), and each Manager 
instance is aware of DB session/connection (via some internal auto-wired 
magic).

I've been reading for a while about design patterns, and have read some 
opinions that Domain Models should not be aware of database-access layer - 
so passing ISession instance to the method would break that rule.
So what is the solution? Should I pass the Repository instance instead? 
Does it even make any sense to have the Repository for every Domain Model, 
since most of them will only be returing IQueryable<DomainModel>?
We have LINQ now, and complex query conditions worth defining own wrapping 
method are not-so-common... 

Moreover, the application I'm working on is a web service based on an 
excellent ServiceStack. The one and only access to the data is through the 
Services, so this is the one and only layer which has direct access to 
NHibernate session - I don't think wrapping Domain Models in one more layer 
is a good idea here.
On the other hand, I'd like to learn "enterprise" design patterns and 
principles. Not necessary use them in my project, just understand what they 
are, and know theirs pros and cons.


Any thought, tips, clarifications, ideas?

On Sunday, September 29, 2013 7:01:31 PM UTC+2, Gunnar Liljas wrote:
>
> And just to add to the confusion, I disagree. I've rarely found it to be 
> of any significant advantage to make my domain model unaware of the 
> persistence mechanism, and quite often it's a major, major disadvantage. A 
> repository which is queryable in any other way than using explicit methods 
> or query objects (in other words, a repository exposing IQueryable) is 
> completely out of the question.
>
> Passing ISession into the business methods may not be necessary (the 
> session can be contextual), but there's nothing really wrong with.
>
> /G 
>
>
> 2013/9/29 Angel Java Lopez <[email protected] <javascript:>>
>
>> +1
>>
>>
>> On Sun, Sep 29, 2013 at 11:01 AM, Oskar Berggren 
>> <[email protected]<javascript:>
>> > wrote:
>>
>>> To give short and quick answer: Ususally I would expect my domain model 
>>> to be unaware oh NHibernate or any other persistence mechanism. Instead of 
>>> passing the ISession, it's better to pass the required repository 
>>> interfaces to a domain class, since the repository interfaces in my view 
>>> are part of the domain model (but not the repository implementation). For 
>>> logic that won't fit nicely inside a domain model class, I would normally 
>>> use a domain service class to orchestrate the algorithm between the 
>>> involved model classes.
>>>
>>> The repository implementation itself should not contain logic beyond 
>>> that of simple store/retrieve/query (and for complex queries it might be 
>>> better to use a query object).
>>> /Oskar
>>>
>>>
>>>
>>> 2013/9/28 mg <[email protected] <javascript:>>
>>>
>>>> Hi,
>>>> What is the proper place to put business some more complex business 
>>>> logic which requires access to other Models, not only the one on which the 
>>>> operation is being executed?
>>>> *Are there any open-source projects which uses a bit of business logic 
>>>> and could be a good example?*
>>>>
>>>> To make myself clear: all the examples of business logic I've found are 
>>>> very simple ones, like *class Person *with calculated property *FullName 
>>>> *which is just a getter: FirstName + " " + LastName, or calculating 
>>>> Person's Age by theirs BirthDate field.
>>>>
>>>> Now I need some more complex logic, for example to calculate the *
>>>> Invoice* amount based on today's *PricingPlan* model which is separate 
>>>> model. 
>>>> Where should I implement methods like this? Is the Repository pattern 
>>>> supposed to be place for this methods?
>>>> Or is it OK to implement these methods in the class it is logically 
>>>> related to, just passing the ISession instance to the method, like so:
>>>>
>>>> class Invoice
>>>> {
>>>>     // ...
>>>>     public void CalculatePrice(ISession dbSess)
>>>>     {
>>>>         var pricePlan = dbSess.Get<PricingPlan>(...); //
>>>>     }
>>>> }
>>>>
>>>> I come from python/django background, and there's no such problem, 
>>>> since the db connection/session management is hidden away from user.
>>>>
>>>> Best regards
>>>> MG
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "nhusers" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to [email protected] <javascript:>.
>>>> To post to this group, send email to [email protected]<javascript:>
>>>> .
>>>> Visit this group at http://groups.google.com/group/nhusers.
>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>>
>>>
>>>  -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "nhusers" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected] <javascript:>.
>>> To post to this group, send email to [email protected]<javascript:>
>>> .
>>> Visit this group at http://groups.google.com/group/nhusers.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>
>>
>>  -- 
>> You received this message because you are subscribed to the Google Groups 
>> "nhusers" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> To post to this group, send email to [email protected]<javascript:>
>> .
>> Visit this group at http://groups.google.com/group/nhusers.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to