Hi,

I am experimenting some issues with the current implementation of interfaces. Specifically, using an interface as the type of a property (of a persistent class) does not seem to work. First, here is a simple example of code that works as expected (a Customer and Address class, where each customer has a billing address of type Address):

public interface IAddress
{
    string Street { get; set; }
}

[HierarchyRoot]
public class Address : Entity, IAddress
{
    [Field, Key]
    public int Id { get; private set; }

    [Field]
    public string Street { get; set; }

    public override string ToString()
    {
       return Street;
    }
}

[HierarchyRoot]
class Customer : Entity
{
    [Field, Key]
    public int Id { get; private set; }

    [Field]
    public string Name { get; set; }

    [Field]
    public Address BillingAddress { get; set; }

    public override string ToString()
    {
       return String.Format("{0} : {1}", Name, BillingAddress);
    }
}

The previous class definition works as expected : In a first transaction, i am able to intantiate Customer persitent objects, and in a second transaction, I am able to list them with Query<customer>.All However, using the IAddress interface is problematic. Here is a detailed description of the problem.

1- First step: Change the type of the BillingAddress field to be an IAddress instead of Address :

[Field]
    public IAddress BillingAddress { get; set; }

This change results in a NotSupportedException : Type Full.Namespace.IAddress is not supported. during the domain build. This error is expected since IAddress is not a persitent interface. Therefore :

2- Second step: change the definition of IAddress to that it inherits IEntity : public interface IAddress : IEntity . As a consequence, the domain build throws a KeyNotFoundException : "The given key was not present in the dictionary".

3- Third step: in Customer class, change the type of BillingAddress to IAddress instead of Address :

[HierarchyRoot]
  class Customer : Entity
  {
    [Field, Key]
    public int CustomerId { get; private set; }

    [Field]
    public string Name { get; set; }

    [Field]
    public IAddress BillingAddress { get; set; }

    public override string ToString()
    {
      return String.Format("{0} : {1}", Name, BillingAddress);
    }
  }

Then the following happens : 1- domain build succeeds, and Customer objects can be persited in the database (I checked in Microsoft SQL Server Management) 2- In another transaction, Query<customer>.All returns a list of Customers, but for all of them, accessing the BillingAddress throws a NullReferenceException : Object reference not set to an instance of an object.

That is to say that the Customer instances seem to have been successfully persisted, as well as the IAddress (both are present in the database), but accessing the BillingAddress is impossible if its type is IAddress (instead of Address). More surprisingly : the data in the database after step 3 is the same as the one given by code that actually works !! (i.e. the code that does not use any interface, at beginning of this post). In both cases, there is a 'BillingAddress.Id' column in Customer table, that contains the Key field of the corresponding Address table.

Moreover, I am surprised that persisting Customer objects is possible in step 3, given that step 2 fails. Did I get something wrong with the persistent interfaces ? Thanks for your feedback.

Best regards,

Auguste

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Sep 07 '09 at 14:17

Auguste's gravatar image

Auguste
25888


One Answer:

Thanks for such a good report... Unfortunately, persistent interfaces aren't really working now:

But as you know, this functionality is already declared as working in Wiki. You may discover that today we're independently of you have started to work on first of these issues, and we plan to finish with them during 2 nearest weeks (likely, earlier, since many parts are already working; although there are no good tests for this). We'll add the code you provided to our test suite as well.

So I can ensure you this feature will be mainly working in either v4.0.6 or v4.1 (i.e. in September). The only subjective part is [MaterializedView] attribute - likely, we will postpone its support, if there will be any complexities related to it.

AFAIK, this is the only feature that is described as implemented, but is completely broken in reality. I'm really sorry for this. We were postponing fixing the bugs there mainly because this functionality is required much rarely, especially on initial stages. As you've just shown (and nice that we felt the same today), this rule isn't intact now.

answered Sep 07 '09 at 18:00

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

(Sep 07 '09 at 18:00) Alex Yakunin Alex%20Yakunin's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

Subscription:

Once you sign in you will be able to subscribe for any updates here

Tags:

×573

Asked: Sep 07 '09 at 14:17

Seen: 2,237 times

Last updated: Sep 07 '09 at 14:17

powered by OSQA