views:

430

answers:

2

I am trying to create a messaging system between users and organizations - that is, a user can send and recieve messages from users or organizations.

So, to support this system, I started with an interface:

public interface IPassableObject<F, T, O>
    where F : DomainObject 
    where T : DomainObject
{
    Guid PassedItemId { get; set; }
    O Item { get; set; }
    F From { get; set; }
    T To { get; set; }
    DateTime Created { get; set; }
}

The idea is later I'd like to be able to pass more than just messages - like serialized objects. So, we have a class with 3 Generic types. The To, the From, and the object

Then I created my Message class

public class Message<T, F> : DomainObject, IPassableObject<T, F, string>
    where F : DomainObject
    where T : DomainObject
{

    public Message()
    {
        Created = DateTime.Now;
    }

    #region IPassableObject<T,F> Members

    public virtual Guid PassedItemId { get; set; }

    public virtual string Item { get; set; }

    public virtual T From { get; set; }

    public virtual F To { get; set; }

    public virtual DateTime Created { get; set; }

    #endregion
}

Then, I made my table to support my passed items:

CREATE TABLE dbo.PassedItems
(
    PassedItemId      uniqueidentifier  NOT NULL,
    FromId     uniqueidentifier  NOT NULL,
    ToId     uniqueidentifier  NOT NULL,
    SerializedObject  varchar(max)   NOT NULL,
    Created     datetime    DEFAULT(GETEDATE()) NOT NULL,

    CONSTRAINT PK_PassedItems PRIMARY KEY CLUSTERED (PassedItemId)
)

The ID's for both my users and organizations are guids. Now, I have my fluent mapping for The User - User messages. My thought is that I will only have to create 4 mappings and not maintain 4 seperate classes for user-user, user-org, org-user, and org-org. I was hoping that Nhibernate would take the guid in the table and automatically try and pull in the object based on the type specified.

public class UserToUserMessageMap : ClassMap<Message<UserProfile, UserProfile>>
{
    public UserToUserMessageMap()
    {
        WithTable("PassedItems");

        Id(x => x.PassedItemId, "PassedItemId").GeneratedBy.Guid();

        Map(x => x.Item, "SerializedObject");
        Map(x => x.Created);

        References(x => x.From, "FromId");
        References(x => x.To, "ToId");
    }
}

The issue I am seeing is that when I run my application, I get a runtime error:

NHibernate.MappingException: An association from the table PassedItems does not specify the referenced entity

So, will this approach even work? What am I doing wrong? Thanks!

A: 

So what does the mapping for 'From' & 'To' look like?

Because I think NH does not how to map these entities because you've not supplied the mapping info.

In general it sounds to me as thought you are re-inventing the wheel, have you looked at technology stacks like web services (SOAP & REST), message queueing, remoting (.Net). And specific implementations like WCF, ASMX (web services), nServiceBus, MassTransit, MSMQ to name just a few...

Ollie

AWC
From and To in this Instance are UserProfile object which are mapped and have been working for some time. I think you misunderstand. A "message" in this case is not a transport protocol. It is an actual messaging system where users recieve messages in an inbox, and eventually I want to be able to expand the system to allow the users and organizations to sent more than just text.
Josh
A: 

I found a solution to my issue. To give a rough overview of what I did:

I had to dump the generics.

I have my interface, IPassable.

I have an abstract class that implements IPassable: PassableBase

I have my "dummy" class PassableItem that is inherited from PassableBase. This class does nothing outside the defaults set in PassableBase.

Message is a class that also inherits from PassableBase. Other passed objects will have to inherit from PassableBase.

My Fluent mapping uses PassableItem.

My repositories use PassableBase for input parameters and I create a new PassableItem or get a PassableItem from the store (depending on if it's created already or not), and then do my save/delete on the PassableItem object.

Josh