I haven't found an answer to this issue yet (neither here nor on 
stackoverflow), so I suppose this is just a shortcoming in the current 
implementation of mapping by code. I've created a IUserType for 
HashedPassword as a workaround for now. HashedPassword is a fairly simple, 
immutable single-column type with value semantics, so the implementation of 
the user type wasn't very difficult. At least I can now use the IPassword 
abstraction and configure the actual type in the mapping.

I'd still really appreciate feedback on why this can't be mapped as a 
component.

Best,
Andre


Am Montag, 11. Februar 2013 21:47:10 UTC+1 schrieb Andre:
>
> In a framework I have an abstraction of a password:
>  
>     public interface IPassword
>     {
>         bool Matches(string password);
>     }
>
> with different implementation that define how the password is represented, 
> for example:
>
>     public class HashedPassword : IPassword
>     {
>         public virtual string Hash { get; set; }
>         public virtual string Salt { get; set; }
>
>         public bool Matches(string password){ return /*...*/; }
>     }
>
> I want to use the abstraction of the password in an entity:
>
>     public class Login
>     {
>         ...
>         public virtual IPassword Password { get; set; }
>     }
>
> Only one specific implementation of IPassword will be used in the 
> application. I use an abstract factory to instantiate the proper 
> implementation of IPassword at runtime.
>
> Now I need to define a mapping for Login. I'd like to map Password as a 
> component. Using XML this can be done with:
>
>   <class name="Login">
>     ...
>     <component name="Password" class="HashedPassword">
>       <property name="Hash" not-null="true" length="32"/>
>       <property name="Salt" not-null="true" length="32"/>
>     </component>
>   </class>
>
> When I use XML mapping this works perfectly fine. However, I can't make it 
> work using mapping-by-code/conformist. Here's an attempt:
>
>     public class LoginMapping : ClassMapping<Login>
>     {
>         public LoginMapping()
>         {
>             ...
>             Component(x => x.Password, comp => {
>                     comp.Class<HashedPassword>();
>                     comp.Property("Salt", map => map.Length(32));
>                     comp.Property("Hash", map => map.Length(32));
>                 });
>         }
>     }
>
> If I try to compile the mapping from this I get the following exception: 
>
> NHibernate.MappingException: Member not found. The member 'Salt' does not 
> exists in type IPassword
>
> Another attempt:
>     public class LoginMapping : ClassMapping<Login>
>     {
>         public LoginMapping()
>         {
>             Id(x => x.Id, map => map.Generator(Generators.HighLow));
>             Property(x => x.UserName, map => map.Length(32));
>             Component(x => x.Password, comp => {
>                     comp.Class<HashedPassword>();
>                     comp.Property(x => (x as HashedPassword).Salt, map => 
> map.Length(32));
>                     comp.Property(x => (x as HashedPassword).Hash, map => 
> map.Length(32));
>                 });
>         }
>     }
>
> Now there's no exception but *no* property of HashedPassword gets mapped 
> at all, ie. the generated mapping for the component is: 
>
>   <component class="HashedPassword" name="Password" />
>
>
> How can I map this component? Or more generally, how can I map components 
> that are exposed as interfaces instead of the concrete type. Do I have to 
> resort to a IUserType? It works when using XML, so hopefully I can get it 
> to work using mapping-by-code.
>
> I have searched the group but haven't found the information to solve this. 
> Your input is very much appreciated!
>
> Regards, 
> Andre
>

-- 
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?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to