I have been playing around with Fluent for a while now, and have been
trying to build a convention that echos how I usually write mapping
files.

One thing I was missing was good support for using Interfaces as
proxies, and generally in the model.
I was pleased to see the "Proxy" patch on ClassInstance, but one thing
that I think was also missing is to be able to set/override the
standard class mapping on a one-to-many mapping.
I'll try to explain.
I usually like to model my collections in my objects like this:
(pseudo code)

public class AutomapProduct : IAutomapProduct
{
        protected IList<IProductAttribute> _attributes = new
List<IProductAttribute>();

        public IEnumerable<IProductAttribute> Attributes
        {
            get { return _attributes; }
            protected set { _attributes =
value.ToList<IProductAttribute>(); }//only here for fluent nh
        }
}

So the collection is declared with IProductAttribute instead of
ProductAttribute.
Obviously, when mapping this, one has to map this to a concrete type.
I know some people consider the above an anti-pattern, but here's not
the place to discuss this, the above is possible in nHibernate, and
it's now possible in Fluent too by using:

HasMany<ProductAttribute>(x => x.Attributes);

However, I don't think it was possible before to set up a convention
that, by default, would try to map it to a concrete type based on the
interface's name.

For this, I added a SetManyClass method on OneToManyInstance to allow
this to be set in a convention.
This allows me to do something like:

public class HasManyConvetion : IHasManyConvention
    {

        public void Apply(IOneToManyCollectionInstance instance)
        {
            //collection may be declared to return interface ->
default to obvious candidate for mapping.
            if (instance.Relationship.ManyClass.GetUnderlyingSystemType
().IsInterface)
            {
                string name =
instance.Relationship.ManyClass.Name.Substring(1);//remove I
                string namesp =
instance.Relationship.ManyClass.GetUnderlyingSystemType().Namespace;
                string assem =
instance.Relationship.ManyClass.GetUnderlyingSystemType
().Assembly.ToString();
                instance.Relationship.SetManyClass(Type.GetType
(string.Concat(namesp, ".", name, ", ", assem)));
            }
        }
    }

Again, I don't really want to discuss the pattern here, I personally
like to use interfaces in collections, but here's not the place to
discuss this pattern, I just want to discuss the Fluent implementation
and conventions ;)

The patch to implement this is is below.

Is this useful? Is it worth adding?



--
Index: Conventions/Instances/IOneToManyInstance.cs
===================================================================
--- Conventions/Instances/IOneToManyInstance.cs (revision 647)
+++ Conventions/Instances/IOneToManyInstance.cs (working copy)
@@ -1,9 +1,17 @@
 using FluentNHibernate.Conventions.Inspections;
+using System;
+using FluentNHibernate.MappingModel;

 namespace FluentNHibernate.Conventions.Instances
 {
     public interface IOneToManyInstance : IOneToManyInspector,
IRelationshipInstance
     {
         INotFoundInstance NotFound { get; }
+
+        TypeReference ManyClass { get; }
+
+        void SetManyClass<T>();
+        void SetManyClass(Type type);
+        void SetManyClass(string type);
     }
 }
\ No newline at end of file
Index: Conventions/Instances/OneToManyInstance.cs
===================================================================
--- Conventions/Instances/OneToManyInstance.cs  (revision 647)
+++ Conventions/Instances/OneToManyInstance.cs  (working copy)
@@ -1,5 +1,7 @@
 using FluentNHibernate.Conventions.Inspections;
 using FluentNHibernate.MappingModel.Collections;
+using System;
+using FluentNHibernate.MappingModel;

 namespace FluentNHibernate.Conventions.Instances
 {
@@ -24,5 +26,28 @@
                 });
             }
         }
+
+        public TypeReference ManyClass
+        {
+            get
+            {
+                return mapping.Class;
+            }
+        }
+
+        public void SetManyClass<T>()
+        {
+            SetManyClass(typeof(T));
+        }
+        public void SetManyClass(Type type)
+        {
+            if(!mapping.IsSpecified("class"))
+                mapping.Class = new TypeReference(type);
+        }
+        public void SetManyClass(string type)
+        {
+            if(!mapping.IsSpecified("class"))
+                mapping.Class = new TypeReference(type);
+        }
     }
 }
\ No newline at end of file



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Fluent NHibernate" group.
To post to this group, send email to fluent-nhibernate@googlegroups.com
To unsubscribe from this group, send email to 
fluent-nhibernate+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/fluent-nhibernate?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to