0

Please consider this interface:

public interface IInitialiazableEntity<TRepository> where TRepository : class, IRepository
{
    void Initialize(TRepository repository);
}

This class (snippet):

public class SomeFacade<TRepository> where TRepository : class, IRepository
{
        public void Add<TEntity>(TEntity entity) where TEntity : AbstractEntity
        {
            try
            {
                if (entity is IInitialiazableEntity<TRepository>)
                    (entity as IInitialiazableEntity<TRepository>).Initialize(this.Repository);
            }
            catch (Exception ex)
            {
                this.Logger.Error(ex);
            }
        }
}

And the entity:

public class Student : AbstractEntity, IInitialiazableEntity<IRepository>
{ 
    void Initialize(IRepository repository) { ... }
}

Since the student is only IInitialiazableEntity<IRepository> and the facade will have an actual repository which is more specialized than the basic IRepository (i.e. it will be IMySpecialRepository : IRepository), will the is keyword realize that it can cast the IMySpecialRepository and pass it to the Initialize method of the entity? Or if not, how to do it?

h.alex
  • 902
  • 1
  • 8
  • 31
  • Have you tried it? Also, what are IMySpecialRepository and IMySpecializedRepository? – ken2k Nov 03 '14 at 13:42
  • I am sorry, I know I can test this, and then try find a solution, but I'm in an extra hurry. And I think It will be useful for other people (given the title/tags are right). – h.alex Nov 03 '14 at 13:45
  • @ken2k the special(ized) repository (there was a typo, both are the same, I corrected it) - is anything inheriting from the base IRepository. – h.alex Nov 03 '14 at 13:47
  • Sure you can do it. The thing is, should you? The actual type should be none of your concerns. – Erti-Chris Eelmaa Nov 03 '14 at 13:51

2 Answers2

1

Assuming your entity is of type Student, the 'is' will return false; this is because Student doesn't implement the more specific interface specialization. You don't need to cast to this more specific interface, though. This should work just fine:

public class SomeFacade<TRepository> where TRepository : class, IRepository
{
        public void Add<TEntity>(TEntity entity) where TEntity : AbstractEntity
        {
            try
            {
                if (entity is IInitialiazableEntity<IRepository>)
                    (entity as IInitialiazableEntity<IRepository>).Initialize(this.Repository);
            }
            catch (Exception ex)
            {
                this.Logger.Error(ex);
            }
        }
}
Dan Bryant
  • 27,329
  • 4
  • 56
  • 102
  • But the Student entity might use the basic IRepository, while some other entity might implement IInitialiazableEntity with a more specialized repository, thus I need to support it. – h.alex Nov 03 '14 at 13:49
  • But the top of the inheritance will be the TRepository that the facade has. No entity will use a more specialized repo than the facade. Or I can just make the entities have to implement the initializable with the most specialized repo, and be done with it, then the is will return true.. what do you think? – h.alex Nov 03 '14 at 13:51
1

Currently, if you had an instance SomeFacade<IMySpecialRepository> the code will not work.

You have two options, one is the answer provided by Dan Bryant, the other is to make IInitialiazableEntity<TRepository> contravariant.

Your interface declaration will become (note the in on the generic type):

public interface IInitialiazableEntity<in TRepository> where TRepository : class, IRepository
{
    void Initialize(TRepository repository);
}

This will allow your is check and cast to work, as IInitialiazableEntity<IRepository> can be cast to IInitialiazableEntity<IMySpecialRepository> when using a contravariant generic.

See here for more information about Covariance and Contravariance in generics.

Lukazoid
  • 19,016
  • 3
  • 62
  • 85
  • Thank you Sir, that one in makes all the difference. I never would've went this way hadn't I asked. Thanks for sharing. – h.alex Nov 03 '14 at 14:10