NHibernate mapping with no empty constructor and no setters - nhibernate

I'm testing how difficult it is to use NHibernate with a domain that is completely unaware of it and isn't bent to accodomate any limitations.
On many examples I found on the web the domain being mapped is yet another example of an anemic domain, where objects don't go far from being simple data holders. Sure, this makes the mapping simple and all and it might appeal to data-centric persons/situations, but I don't like hearing the voices in my head that say "C has structs too, you know?", "Classes are not just fancy namespaces, you know?", or "Why don't you use CREATE TABLE instead?".
But back to NHibernate. NHibernate forces me to make properties virtual to be able to proxy them for lazy loading. This is something I don't mind, as I might need them as virtual for some AOP stuff too.
The limitations I'm not happy with are the need for an empty constructor and the need for setters/properties. I want my entities to be created in a valid state, and most of the time that means no empty constructor.
I also don't want to expose setters for collection properties, for the usual reasons. Oh, and setters for attributes that are not supposed to be changed directly.
Consider this simplified and contrived aggregate in a domain model somewhere:
public class ShoppingCartItem
{
private readonly Product product;
public ShoppingCartItem(Product product, int quantity)
{
if(quantity <= 0)
throw new ArgumentOutOfRangeException("quantity");
this.product = product;
this.quantity = quantity;
}
public virtual Product Product
{
get { return product; }
}
private int quantity;
public virtual int Quantity
{
get { return quantity; }
set
{
if(value <= 0)
throw new ArgumentOutOfRangeException("value");
quantity = value;
}
public virtual Money TotalPrice
{
get { return product.Price * quantity; }
}
}
public class ShoppingCart : Entity
{
private readonly IDictionary<Product, ShoppingCartItem> items =
new Dictionary<Product, ShoppingCartItem>();
private readonly ISet<DiscountCoupon> discountCoupons =
new HashSet<DiscountCoupon>();
public virtual IEnumerable<ShoppingCartItem> Items
{
get { return items.Values; }
}
public virtual IEnumerable<DiscountCoupon> DiscountCoupons
{
get { return discountCoupons; }
}
public virtual void AddProduct(Product product)
{
ShoppingCartItem item;
if(items.TryGetValue(product, out item))
item.Quantity++;
else
items.Add(product, new ShoppingCartItem(product, 1));
}
public virtual void RemoveProduct(Product product)
{
ShoppingCartItem item;
if(!items.TryGetValue(product, out item))
throw new ArgumentException("product");
if(item.Quantity == 1)
items.Remove(product);
else
item.Quantity--;
}
public virtual int AddDiscountCoupon(DiscountCoupon coupon)
{
discountCoupons.Add(coupon);
}
public virtual int RemoveDiscountCoupon(DiscountCoupon coupon)
{
discountCoupons.Remove(coupon);
}
public virtual Money CalculatePrice()
{
// Missing complex discount logic
return items.Values.Sum(item => item.TotalPrice);
}
}
Most properties have no setter, and there are no empty constructors in sight. Collections are not meddled with directly, but through specialized methods. Can I make use of NHibernate's extensibility to map this? Or am I trying to hammer a screw again? Or both?

Well you can put private/internal/protected setters on properties/collections and nhibernate will load them up properly (chapter 4.1.1)
The constructor has to be there but you are not obliged to make it a public one (chapter 4.1.2)
chapter ref from the latest http://sourceforge.net/projects/nhibernate/files/NHibernate/2.1.2GA/NHibernate-2.1.2.GA-reference.zip/download

First off you can make the empty constructor private so that nobody else can access it. NH will still be able to get to it.
Second off NH can access your properties however you want.
access="backfield" is used for public virtual Product Product { get; private set; }
access="field.pascalcase-m-underscore" for m_Product
access="field.pascalcase-underscore" for _Product
There are other access strategies and I'm pretty sure you can even create your own if need be.

Related

OO programming issue - State Design Pattern

I have spent the last day trying to work out which pattern best fits my specific scenario and I have been tossing up between the State Pattern & Strategy pattern. When I read examples on the Internet it makes perfect sense... but it's another skill trying to actually apply it to your own problem. I will describe my scenario and the problem I am facing and hopefully someone can point me in the right direction.
Problem: I have a base object that has different synchronization states: i.e. Latest, Old, Never Published, Unpublished etc. Now depending on what state the object is in the behaviour is different, for example you cannot get the latest version for a base object that has never been published. At this point it seems the State design pattern is best suited... so I have implemented it and now each state has methods such as CanGetLatestVersion, GetLatestVersion, CanPublish, Publish etc.
It all seems good at this point. But lets say you have 10 different child objects that derive from the base class... my solution is broken because when the "publish" method is executed for each state it needs properties in the child object to actually carry out the operation but each state only has a reference to the base object. I have just spent some time creating a sample project illustrating my problem in C#.
public class BaseDocument
{
private IDocumentState _documentState;
public BaseDocument(IDocumentState documentState)
{
_documentState = documentState;
}
public bool CanGetLatestVersion()
{
return _documentState.CanGetLatestVersion(this);
}
public void GetLatestVersion()
{
if(CanGetLatestVersion())
_documentState.CanGetLatestVersion(this);
}
public bool CanPublish()
{
return _documentState.CanPublish(this);
}
public void Publish()
{
if (CanPublish())
_documentState.Publish(this);
}
internal void Change(IDocumentState documentState)
{
_documentState = documentState;
}
}
public class DocumentSubtype1 : BaseDocument
{
public string NeedThisData { get; set; }
}
public class DocumentSubtype2 : BaseDocument
{
public string NeedThisData1 { get; set; }
public string NeedThisData2 { get; set; }
}
public interface IDocumentState
{
bool CanGetLatestVersion(BaseDocument baseDocument);
void GetLatestVersion(BaseDocument baseDocument);
bool CanPublish(BaseDocument baseDocument);
bool Publish(BaseDocument baseDocument);
SynchronizationStatus Status { get; set; }
}
public class LatestState : IDocumentState
{
public bool CanGetLatestVersion(BaseDocument baseDocument)
{
return false;
}
public void GetLatestVersion(BaseDocument baseDocument)
{
throw new Exception();
}
public bool CanPublish(BaseDocument baseDocument)
{
return true;
}
public bool Publish(BaseDocument baseDocument)
{
//ISSUE HERE... I need to access the properties in the the DocumentSubtype1 or DocumentSubType2 class.
}
public SynchronizationStatus Status
{
get
{
return SynchronizationStatus.LatestState;
}
}
}
public enum SynchronizationStatus
{
NeverPublishedState,
LatestState,
OldState,
UnpublishedChangesState,
NoSynchronizationState
}
I then thought about implementing the state for each child object... which would work but I would need to create 50 classes i.e. (10 children x 5 different states) and that just seems absolute crazy... hence why I am here !
Any help would be greatly appreciated. If it is confusing please let me know so I can clarify!
Cheers
Let's rethink this, entirely.
1) You have a local 'Handle', to some data which you don't really own. (Some of it is stored, or published, elsewhere).
2) Maybe the Handle, is what we called the 'State' before -- a simple common API, without the implementation details.
3) Rather than 'CanPublish', 'GetLatestVersion' delegating from the BaseDocument to State -- it sounds like the Handle should delegate, to the specific DocumentStorage implementation.
4) When representing external States or Storage Locations, use of a separate object is ideal for encapsulating the New/Existent/Deletion state & identifier, in that storage location.
5) I'm not sure if 'Versions' is part of 'Published Location'; or if they're two independent storage locations. Our handle needs a 'Storage State' representation for each independent location, which it will store to/from.
For example:
Handle
- has 1 LocalCopy with states (LOADED, NOT_LOADED)
- has 1 PublicationLocation with Remote URL and states (NEW, EXIST, UPDATE, DELETE)
Handle.getVersions() then delegates to PublicationLocation.
Handle.getCurrent() loads a LocalCopy (cached), from PublicationLocation.
Handle.setCurrent() sets a LocalCopy and sets Publication state to UPDATE.
(or executes the update immediately, whichever.)
Remote Storage Locations/ Transports can be subtyped for different methods of accessing, or LocalCopy/ Document can be subtyped for different types of content.
THIS, I AM PRETTY SURE, IS THE MORE CORRECT SOLUTION.
[Previously] Keep 'State' somewhat separate from your 'Document' object (let's call it Document, since we need to call it something -- and you didn't specify.)
Build your heirarchy from BaseDocument down, have a BaseDocument.State member, and create the State objects with a reference to their Document instance -- so they have access to & can work with the details.
Essentially:
BaseDocument <--friend--> State
Document subtypes inherit from BaseDocument.
protected methods & members in Document heirarchy, enable State to do whatever it needs to.
Hope this helps.
Many design patterns can be used to this kind of architecture problem. It is unfortunate that you do not give the example of how you do the publish. However, I will state some of the good designs:
Put the additional parameters to the base document and make it
nullable. If not used in a document, then it is null. Otherwise, it
has value. You won't need inheritance here.
Do not put the Publish method to the DocumentState, put in the
BaseDocument instead. Logically, the Publish method must be part
of BaseDocument instead of the DocumentState.
Let other service class to handle the Publishing (publisher
service). You can achieve it by using abstract factory pattern. This
way, you need to create 1:1 document : publisher object. It may be
much, but you has a freedom to modify each document's publisher.
public interface IPublisher<T> where T : BaseDocument
{
bool Publish(T document);
}
public interface IPublisherFactory
{
bool Publish(BaseDocument document);
}
public class PublisherFactory : IPublisherFactory
{
public PublisherFactory(
IPublisher<BaseDocument> basePublisher
, IPublisher<SubDocument1> sub1Publisher)
{
this.sub1Publisher = sub1Publisher;
this.basePublisher = basePublisher;
}
IPublisher<BaseDocument> basePublisher;
IPublisher<SubDocument1> sub1Publisher;
public bool Publish(BaseDocument document)
{
if(document is SubDocument1)
{
return sub1Publisher.Publish((SubDocument1)document);
}
else if (document is BaseDocument)
{
return basePublisher.Publish(document);
}
return false;
}
}
public class LatestState : IDocumentState
{
public LatestState(IPublisherFactory factory)
{
this.factory = factory;
}
IPublisherFactory factory;
public bool Publish(BaseDocument baseDocument)
{
factory.Publish(baseDocument);
}
}
Use Composition over inheritance. You design each interface to each state, then compose it in the document. In summary, you can has 5 CanGetLatestVersion and other composition class, but 10 publisher composition class.
More advancedly and based on the repository you use, maybe you can use Visitor pattern. This way, you can has a freedom to modify each publishing methods. It is similiar to my point 3, except it being declared in one class. For example:
public class BaseDocument
{
}
public class SubDocument1 : BaseDocument
{
}
public class DocumentPublisher
{
public void Publish(BaseDocument document)
{
}
public void Publish(SubDocument1 document)
{
// do the prerequisite
Publish((BaseDocument)document);
// do the postrequisite
}
}
There may be other designs available but it is dependent to how you access your repository.

Fluent NHibernate ShouldMap does not detect my custom attribute

I have been spending a couple of days now to get to know the Fluent NHibernate automapping working model. It is quite nice, but I keep detecting new details missing from my schemas. Now I want to add extra properties to my classes, but not have them mapped to the database. A typical case is when I need extra properties with internal logic.
So I read the examples and scanned StackOverflow and found out that this was not another convention to be added, but rather a matter of inheriting the DefaultAutomappingConfiguration and override the ShouldMap method.
Fine, no problem, one minute later I had something like this:
public class CustomAutomappingConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Member member)
{
var explicitSkip = member.PropertyType.GetCustomAttributes(typeof(SkipMap), false).Length > 0;
if ((member.IsProperty && !member.CanWrite) || explicitSkip)
{
return false;
}
return base.ShouldMap(member);
}
}
/// <summary>
/// Don't map this property to database.
/// </summary>
public class SkipMap : Attribute
{
}
public class DemoClass
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual MyBitwiseEnum Status { get; set; }
public virtual bool IsValid
{
get
{
return (int)Status > 3;
}
}
[SkipMap]
public virtual bool IsBad
{
get
{
return MyBitwiseEnum.HasFlag(MyBitwiseEnum.Bad);
}
set
{
MyEnum = value ? MyBitwiseEnum | MyBitwiseEnum.Bad : MyBitwiseEnum ^ MyBitwiseEnum.Bad;
}
}
}
I know that my demo class is kind of stupid, but it will illustrate my point.
The idea is that I want to manually decide what properties to map to database.
The readonly property works fine because the ShouldMap method will look for property.CanWrite. But the custom attribute that definitely is set will not be detected. Why is that!?
In the convention methods I have used the same approach frequently and there it works fine. Why is the property not able to detect defined attributes here, when it obviously can in the convention setting. Is there a workaround?
have you added your new automapconvention to Automap?
AutoMap.AssemblyOf<>(new CustomAutomappingConfiguration())
Update: you are getting the skip attribute from Boolean class instead of the property
member.PropertyType.GetCustomAttributes(typeof(SkipMap), false)
should be
member.MemberInfo.GetCustomAttributes(typeof(SkipMap), false)
Just to be sure the custom attribute is applicable to properties, try adding [AttributeUsage(AttributeTargets.Property)] to your SkipMap class.
Another possibility is an attribute name clash with another attribute that applies to different targets. Try renaming the class to something like MyVerySpecialSkipMap and retest to verify you don't have an attribute clash. At the very least, write some simple reflection code to test for the SkipMap attribute outside the context of your application to ensure it can be found.

Serialising classes that implement List<T> for transferring over WCF

I have spent some time writing code for my application assuming that the serialisation bit would be the easiest part of it. Pretty much both sides (client and server) are done and all I need to do is passing a class AccountInfo from the service to the client... The problem is that AccountInfo inherits List and therefore [DataContract] attribute is not valid. I tried using the [CollectionDataContract] attribute but then the class that is received on the other side (client) contains only generic List methods without my custom implemented properties such as GroupTitle...I have worked out a solution for this problem but I don't know how to apply it.
Basically everything works when I make a property instead of inheriting a List but then I can't bind this class to LongListSelector (WP7) because it's not a collection type.
There are three classes I'm on about. AccountInfo that contains multiple instances of: AccountInfoGroup that contains multiple instances of:AccountInfoEntry (this one does not inherit list therefore there are no problems serialising it and all properties are accessible).
Could someone help me using right attributes to serialise and transfer these classes using a WCF method?
Here is the code of 2 of these collection classes:
public class AccountInfo : List<AccountInfoGroup>
{
public AccountInfo()
{
UpdateTime = DateTime.UtcNow;
EntryID = Guid.NewGuid();
}
public bool HasItems
{
get
{
return (Count != 0);
}
private set
{
}
}
public Guid EntryID
{
get;
set;
}
public decimal GetTotalCredit()
{
decimal credit = 0;
foreach (AccountInfoGroup acg in this.Where(item => item.Class == AccountInfoEntry.EntryType.Credit))
{
acg.Where(item => item.ItemClass == AccountInfoEntry.EntryType.Credit).ToList().ForEach(entry =>
{ credit += entry.Remaining; }
);
}
return credit;
}
public bool UsedForCreditComparison = false;
public DateTime UpdateTime { get; private set; }
}
public class AccountInfoGroup : List<AccountInfoEntry>
{
public AccountInfoEntry.EntryType Class
{
get;
private set;
}
public string Title
{
get
{
return AccountInfoEntry.ClassToString(Class);
}
}
public AccountInfoGroup(AccountInfoEntry.EntryType groupClass)
{
this.#Class = groupClass;
}
public bool HasItems
{
get
{
return (Count != 0);
}
private set
{
}
}
}
Thank you for any suggestions... :)
The sample you had is quite painful for WCF in serialization.
What I suggest is you to revised and have a common models for your WCF messages (That means it only contains properties with getter and setter, serialization attributes).
If you have a problem in LongListSelector binding in WP7, you might want to convert the message to the actual type the WP7 object supports to use in binding.

Association properties on Entity not loaded for server-side validation

Consider the following situation. I have an Entity named ProductSupplier that is a Presentation Model. It is created by doing an inner join of Products and Suppliers, and creating a new projection from a Linq statement. The ProductSupplier projection also creates a list of PartType objects, which is also a Presentation Model.
public partial class ProductSupplier
{
private IEnumerable<PartType> _partTypes;
[Key]
public int ProductSupplierKey { get; set }
[Include]
[Association("ProductSupplier_PartType", "ProductSupplierKey", "ProductSupplierKey")]
public IEnumerable<PartType> PartTypes
{
get { return _partTypes ?? (_partTypes = new List<PartType>()); }
set { if (value != null) _partTypes = value; }
}
}
public partial class PartType
{
[Key]
public int PartTypeKey { get; set; }
[Key]
public int ProductSupplierKey { get; set; }
public int PartQuantity { get; set; }
}
I want to have a validation that is no ProductSupplier can be have more than 10 separate parts. This means that all PartQuantities for all PartTypes that belong to a ProductSupplier should be summed, and the total cannot exceed 10.
For this, I created a custom validator:
public static ValidationResult ValidatePartTotals(ProductSupplier productSupplier, ValidationContext validationContext)
{
if (productSupplier.PartTypes.Sum(p => p.PartQuantity) > 10)
return new ValidationResult("Must be less than 10 parts total.");
return ValidationResult.Success;
}
This works fine when validation is called from the client-side. The problem I'm having is that when the validator is run from the server-side, the IEnumerable is always empty.
I have tried adding [RoundTripOriginal] to the PartQuantity, and to various other properties, such as all the Key fields, but it still is an empty list when done on the server side.
How can I access these PartType objects when validation is run on the server?
Unfortunately, you don't have any guarantees as to the state of the object graph when it gets to you on the server. RIA optimizes things so you'll only see modified entities. One solution would be to use composition. It will make sure the whole graph is passed around, but it has other effects that may not be what you want. Another option would be to hydrate the graph in your update method, then perform validation, and throw a ValidationException as necessary.

(Fluent) NHibernate - Inhertiance on object level but not on table level

I have the following idea:
Business object implemented as interface or abstract class with certain properties as read only to all layers except the DAL layer. I also want my business objects in another assembly than the DAL (for testing purposes), so marking the properties is not an option for me.
Examples could be one to one relationships or other properties.
I have almost solved the issue by doing the following
abstract class User
{
public virtual long UserId {get; protected set;}
public virtual string Password {get; protected set;}
...
}
In the DAL:
public class DbUser : User
{
internal virtual void SetPassword(string password) {...}
}
I then map this using fluent as
ClassMap<User> {...}
SubclassMap<DbUser> {...}
The problem I get is that fluent tries to create a table named DbUser.
If I skip the SubclassMap and creates a DbUser object and tries to save it I get an "No persister for this object" error.
Is it possible to solve?
You could probably override what is done with Fluent
public class DbUser: IAutoMappingOverride<DbUser>
{
public void Override(AutoMapping<DbUser> mapping)
{
//tell it to do nothing now, probably tell it not to map to table,
// not 100% on how you'd do this here.
}
}
Or you could have an attribute
public class DoNotAutoPersistAttribute : Attribute
{
}
And in AutoPersistenceModelGenerator read for attribute in Where clause to exclude it.
Check would be something like
private static bool CheckPeristance(Type t) {
var attributes = t.GetCustomAttributes(typeof (DoNotAutoPersistAttribute), true);
Check.Ensure(attributes.Length<=1, "The number of DoNotAutoPersistAttribute can only be less than or equal to 1");
if (attributes.Length == 0)
return false;
var persist = attributes[0] as DoNotAutoPersistAttribute;
return persist == null;
}
Then it kind of depends how you're adding entities but you're probably adding via assembly so this might do it for you:
mappings.AddEntityAssembly(typeof(User).Assembly).Where(GetAutoMappingFilter);
....
...
private static bool GetAutoMappingFilter(Type t)
{
return t.GetInterfaces().Any(x => CheckPeristance(x)); //you'd probably have a few filters here
}