tags:

views:

160

answers:

2

I have the following domain object:

public class DomainObject<T,TRepo> 
  where T : DomainObject<T>
  where TRepo : IRepository<T>
{
      public static TRepo Repository { get;private set; }
}

A repository interface:

public interface IRepository<T> //where T : DomainObject<T> // The catch 22
{
    void Save(T domainObject);
}

An implementation of the 2:

public class User : DomainObject<User,MyRepository>
{
    public string Name { get;private set;}
}

public class MyRepository : IRepository<User>
{
    public List<User> UsersWithNameBob()
    {

    }
}

So adding another method that isn't inside IRepository.

I want to enforce the repository as an IRepository while above it could be any type.

A small sidenote: I'm writing this for small systems with very few domain objects. I'm not looking to create anything that uses IoC, but rather something that is easy and simple to consume.

Thanks

+4  A: 

Your implementation of DomainObject is only specifying one generic type argument instead of two. Why isn't it:

public class User : DomainObject<User, MyRepository>
{
    public string Name { get;private set;}
}

If that doesn't work, could you explain in what way it doesn't do what you need?

Jon Skeet
That was an oversight, fixed it now
Arec Barrwin
For the second point, I want to avoid casting to my custom Repository in order to access the additions it provides ontop of IRepository
Arec Barrwin
Well I just tested it, and it all seems to work fine. `DomainUser.Repository.UsersWithNameBob();` worked out A-OK.
JustLoren
You won't need to cast: `User.Repository` will be of type `MyRepository`.
Jon Skeet
agreed, I dont see the issue at all.
Lee Treveil
My explanation was confusing. I'll update it - what I meant was MyRepository<string> would work , Lucero's understood me somehow
Arec Barrwin
+3  A: 

Not exactly sure what you want, but something like this compiles:

public class DomainObject<T, TRepo> 
     where T: DomainObject<T, TRepo> 
     where TRepo: IRepository<T, TRepo>
{
     public static TRepo Repository
     {
         get;
         private set; 
     }
}

public interface IRepository<T, TRepo>
     where T: DomainObject<T, TRepo>
     where TRepo: IRepository<T, TRepo>
{
     void Save(T domainObject);
}
Lucero
This was what I was after :) It feels a bit unnatural telling the interface that it is an IRepository, as it's implementing it
Arec Barrwin
Well, you did the same thing already with the domain object ;)
Lucero