views:

158

answers:

2

This question is related to a previous post of mine Here. Basically, I want to inject a DAO into an entity i.e.

public class User
{
   IUserDAO userDAO;
   public User()
   {
         userDAO = IoCContainer.Resolve<IUserDAO>;
   }
  public User(IUserDAO userDAO)
   {
         this.userDAO = userDAO;
   }
   //Wrapped DAO methods i.e
   public User Save()
   {
       return userDAO.Save(this);
   }

}

Here if I had a custom methods in my DAO then I basically have to wrap them in the entity object. So if I had a IUserDAO.Register() I would then have to create a User.Register() method to wrap it.

What would be better is to create a proxy object where the methods from the DAO are dynamically assign to the User object. So I may have something that looks like this:

var User = DAOProxyService.Create(new User());
User.Save();

This would mean that I can keep the User entity as a pretty dumb class suitable for data transfer over the wire, but also magically give it a bunch of DAO methods.

This is very much out of my confort zone though, and I wondered what I would need to accomplish this? Could I use Castles Dynamic proxy? Also would the C# compiler be able to cope with this and know about the dynamically added methods?

Feel free to let me know if this is nonsense.

EDIT:

What we need to do it somehow declare DAOProxyService.Create() as returning a User object -- at compile time. This can be done with generics.

This isnt quite true, what I want to return isn't a User object but a User object with dynamically added UserDAO methods. As this class isn't defnied anywhere the compiler will not know what to make of it.

What I am essentially returning is a new object that looks like: User : IUserDAO, so I guess I could cast as required. But this seems messy.

Looks like what I am looking for is similar to this: Mixins

A: 

I was initially going to say what you ask cannot work. But with some tweaking, we might be able to get it to work.

var is just a compiler feature. When you say.

 var x = GetSomeValue();

the compiler says "'GetSomeValue' is defined as returning a string, so the programmer must of meant to write 'string x = GetSomeValue();'". Note that the compiler says this; this change is done at compile time.

You want to define a class (DAOProxyService) which essentially returns an Object. This will work, but "var User" would be the same as "Object user".

What we need to do it somehow declare DAOProxyService.Create() as returning a User object -- at compile time. This can be done with generics:

class DAOProxyService
{
     static DAOProxyService<T> Create<T>(T obj) { ......} 
}
James Curran
A: 

It's not entirely automatic, but you might consider using a variation of Oleg Sych's method for generating decorator classes. Whenever IUserDAO changes (new method, etc) just regenerate the file. Better than maintaining it manually :-)

http://www.olegsych.com/2007/12/how-to-use-t4-to-generate-decorator-classes/

Russ
Going to play around with proxy generation for a bit, but ill come back to this. Looks interesting anyway.
Owen