Cast a concrete class instance to an interface that uses generics - c#

Here is my concrete Repository that derives from an abstract base class
public class DepartmentRepository : RepositoryBase<Department>, IDepartmentRepository
public abstract class RepositoryBase<T> : IRepository<T> where T : class, IPersistantBusinessObject
Here is my interfaces
public interface IDepartmentRepository : IRepository<Department>
public interface IRepository<T> where T : IPersistantBusinessObject
public interface IPersistantBusinessObject { ... }
And here is my entities
public class Department : BusinessObjectBase
public abstract class BusinessObjectBase : IPersistantBusinessObject
How do I cast my DepartmentRepository to the generic IRepository?
DepartmentRepository rep = new DepartmentRepository();
(IRepository<IPersistentBusinessObject>)rep; // this doesn't work
Ideas? In case you're wondering, this is an asp.net MVC3 application using the repository pattern. Did I over architect the interfaces? How am I suppose to use a generic repository now?
Thanks.
EDIT:
Here is my IRepository interface. As asked about why I need to cast to IRepository, it is actually only so I can use the "SaveChanges" method, because I want to intercept any exceptions from the database and handled in a common way.
public interface IRepository<T> where T: IPersistantBusinessObject
{
IQueryable<T> Retrieve();
T Retrieve(int id);
IQueryable<T> RetrieveActiveAndInActive();
T RetrieveActiveAndInActive(int id);
void Add(T domainObject);
void SaveChanges();
void Delete(T domainObject);
void Delete(int id)
}

What are you trying to do here? I can't think of a situation in which you would want to cast to IRepository<IPersistentBusinessObject>. What code is dependent on what abstraction?
I would usually expect other code to depend on the abstraction of IDepartmentRepository, and can't really see the use case for IRepository<T> or even IPersistentBusinessObject at all. Again, if you can find a use case for code that depends on that abstraction, then they are valuable; otherwise, YAGNI.
(By the way, this is one reason why test-driven development is valuable. You can figure out which abstractions you need by writing unit tests, and seeing what classes need to be mocked to isolate testing of certain functionality, instead of just vaguely abstracting everything into interfaces because you were told they were better than concrete types. Start with concrete types, and when your tests force you to extract an interface, that's the right time!)
Really though, this is a question of covariance of generic types. It should work if you say
public interface IRepository<out T> where T : IPersistantBusinessObject

You need to cast it to IRepository<Department>.
DepartmentRepository derives from RepositoryBase<Department> which implements IRepository<Department>.
You might want to have a look at co and contravariance...

As Daniel implies, you can't cast it to IRepository, because you've defined the IRepository interface to only exist in conjunction with another type T. So "IRepository" as an interface does not exist.
If you want to be able to use an interface "IRepository" then it needs to be a standalone interface without the type dependence.
Perhaps you need two interfaces, one which implements the basic functionality you want in IRepository, and one which implements the generic methods for type T.
e.g.
<!-- language: lang-c# -->
public interface IRepository
{
SaveChanges()
...
}
public interface IRepositoryFor<T> where T : IPersistantBusinessObject
{
T GetFirst(); // or whatever
...
}

Related

Can I override the properties and functions of a generically typed interface extending a non generic interface to consider generic type(s) in C#

What I have is a non generic interface for the purpose of having a common contact that I can call functions. The interface returns objects which implement other interfaces. For example:
public interface ISearchAdvancedInputController
{
ISearchAdvancedInput GetAdvancedInput();
void LoadFromModel(ISearchAdvancedInput advancedInput);
}
I then currently have an abstract generic class which implements the interface but imposes requirements of the type. The types of the abstract class must implement the same interfaces as the interface's properties and functions demand. I cast the generic type to the implemented type when necessary so that I can satisfy the requirements of the implemented non abstract interface. This way, I can extend this abstract class and it will enforce type requirements across a larger class w/ many different types used across it. For example:
public abstract class ISearchAdvancedInputControllerBase<standardInput, advancedInputType> : ISearchAdvancedInputController
where advancedInputType : ISearchAdvancedInput
{
protected abstract advancedInputType GetAdvancedInput();
ISearchAdvancedInput ISearchAdvancedInputController.GetAdvancedInput()
{
return GetAdvancedInput();
}
void ISearchAdvancedInputController.LoadFromModel(ISearchAdvancedInput advancedInput)
{
LoadFromModel((advancedInputType)advancedInput);
}
public abstract void LoadFromModel(advancedInputType advancedInput);
}
This works really well in general however it falls short because I'm having to use an abstract CLASS in order to perform this overriding. As such when I want to actually make use of it for more concrete examples, I encounter the error that I can only extend a single class.
So to get around this I extend the "other" class in the previous base abstract class. However this is not ideal because if I wind up creating another concrete implementation I need to redefine all of the type translations that I'm doing which is NOT related to the concrete classes implementation.
What I'd like is to not have an abstract class but instead some sort of abstract interface. If I had this I'd be able to implement concrete classes more succinctly. I've looked at other instances of this question and have tried what seems to be the main suggestion which is to make the initial interface generic and have the type extend the resulting interface type and then extend that interface with the more abstract interface as such:
interface TestGenericInterface<a> where a:TestClassInterfaceA
{
TestClassInterfaceA testGeneric { get; }
}
interface TestGenericComplexInterface<a> : TestGenericInterface<a>
where a:TestClassInterfaceA
{
new a testGeneric { get; }
}
However the concrete class seems to suffer from the same issue that's shown when you start from a non generic interface where each function / property of the base interface needs overwritten.
public class TestClass : TestGenericComplexInterface<TestGC>
{
public TestGC testGeneric => I want to complete this because its return is the type that I'm wanting to use for this concrete implementation
TestClassInterfaceA TestGenericInterface<TestGC>.testGeneric => I don't want to have to complete this because this function is already handled by the previous function in a round about sense.
}
public class TestGC : TestClassInterfaceA { }
I do see a note that I could provide default implementation of functions if I use c# v8.0 or greater, so I must be on a version prior to that but I figure this should be possible w/o that, but maybe in a different way. Hope ya'll can assist.

Use reflection to forcefully cast object into interface it sort of implements

I have the following setup:
public interface IRepository<T>
{
void Save(T entity);
}
public interface IEmailRepository : IRepository<Email> {} // completely empty!
public class MockRepository<T> : IRepository<T> {}
What I wish to do is the following:
void SomeBusinessMethod(IEmailRepository repo) { ... }
MockRepository<Email> mockRepository = CreateMockRepository<Email>();
IEmailRepository mockedEmailRepository = (IEmailRepository) mockRepository; // Invalid cast!
BusinessMethod(mockedEmailRepository);
I am aware that this isn't possible because MockRepository<T> does not inherit from IEmailRepository, even through the class and interface have the exact same signatures.
This is done in a production project and my goal is to inject a mock repository into business classes. I would prefer the possibility of using reflection to forcefully do this conversion anyways to not update the business logic code.
I found that you can use TypeBuilder and ModuleBuilder to create new types and methods with IL, but I just want to assign an interface to an instance that already sort of implements it. Is there a way to achieve this?
There are several other questions slightly related to this problem, but none have been answered with a solution that allows this setup.

Should we use an interface as dependency (in ctor) even if what we expect is one specific implementation?

Let's say we have a class, for example SqlIdProvider, that needs an SQL repository to perform some operations. We also have an SqlRepository class that implements an IRepository interface like follows:
public interface IRepository {
// All repository methods here.
}
public sealed class SqlRepository : IRepository {
// All repository methods here.
}
public sealed class SqlIdProvider {
private IRepository _repository;
public SqlIdProvider(IRepository repository){
_repository = repository;
}
}
The SqlIdProvider has a strong dependency on SqlRepository, so it will not work if I provide, for example, an instance of the following class:
public sealed class MongoRepository : IRepository {
// All repository methods here.
}
However, the signature of SqlIdProvider tells me that I could just provide one of these and everything should be fine.
In this situation, I usually think of three options:
1) Keep as is, and hope that the name will be enough for others to know that you shouldn't provide a MongoRepository to an SqlIdProvider (though not enforcing it in any way).
2) Change the SqlIdProvider constructor to take the concrete SqlRepository. This would enforce the requirement, but it would difficult unit testing, forcing us to remove the sealed keyword from SqlRepository to be able to fake the implementation (btw, I like classes to be sealed unless there's a good reason not to).
3) Create an empty interface that extends IRepository, designated for the sole purpose of SQL repositories, called ISqlRepository. Now, we could change the SqlIdProvider constructor to take the ISqlRepository interface instead.
public interface ISqlRepository : IRepository {
// This one is empty on purpose.
}
To me, option 3) seems to be the most appealing, however still feels a like I'm doing something wrong here by creating an empty interface.
Is there any better way we can be explicit with the constraint and at the same time allow easy unit testing?

Can we use Abstract class instead of interface [duplicate]

This question already has answers here:
Interface vs Abstract Class (general OO)
(36 answers)
Closed 7 years ago.
i have started career as support developer but i have dream to get a job for S/W dev.
i am learning OOPS with C#. often one thing bug me that is interface and abstract class usage. when to use interface and when to use abstract class. i search google on this topic but whatever the answer i browse and i saw all people try to explain what is abstract and interface but i am not after their definition rather i want see their real usage in real world program. here i like to highlight one code where interface is used but i think the full things can be design with abstract class too.
see the below code of repository design pattern where interface has been used
if i expose repository as interface
public interface IEmployeeRepository
{
Employee[] GetAll();
}
then advantage will be i could have as many implementations as i like as below
public class EmployeeRepositoryEF: IEmployeeRepository
{
public Employee[] GetAll()
{
//here you will return employees after querying your EF DbContext
}
}
public class EmployeeRepositoryXML: IEmployeeRepository
{
public Employee[] GetAll()
{
//here you will return employees after querying an XML file
}
}
public class EmployeeRepositoryWCF: IEmployeeRepository
{
public Employee[] GetAll()
{
//here you will return employees after querying some remote WCF service
}
}
see the above code which has one contract method GetAll()
and who ever will extend the interface then they can provide their own implementation. that is the advantage but my question can i write abstract class instead of interface here ?
suppose i have one abstract class
abstract class AbsEmployeeRepository
{
abstract public Employee[] GetAll();
}
now my all other repository will extend the abstract class AbsEmployeeRepository
and override the function GetAll() to give their own implementation.
now the question is if abstract class can solve my purpose then why we need interface in this scenario. where multiple inheritance is concern then interface will be preferred other wise we can complete job with abstract class.
looking for valuable comments and suggestions. thanks
You would use an abstract class, when you have
Code to be shared.
Default behaviour in methods, but want users of your class to be able to override it.
You would use an interface when
There is no shared code.
It needs to be applied to many objects, with no common base class.
To make the definitions of public methods clearer and provide documentation.
You wish the source code to be private.
Often you would use an abstract class (for shared code) together with an interface (for documentation).
Interface provides only "description" of your future classes, while abstract classes used when you need to have some "unfinished functionality". So if you want to have a class with some logic provided and some unimplemented functions - you should use abstract class, but if all the functions is not implemented - use interface instead.
You should use an abstract class IF all your implementation share a common code basis implementation. That means, the interface will guarantee, that all classes have the same members, but each one must have its own implementation for them.
If you have an abstract class as base, all inheriting classes share the same implementation unless they override it, which is in many cases not needed, often you need to implement only a hand full of members differently.
Interface - guarantee same members.
Abstract class - share common code basis.
Some nice thoughts about it got mentioned on my question for this, maybe this helps you out.
You use abstract classes when you need to provide more than just abstract members to implement but also some concrete member:
public abstract class A
{
protected abstract void DoSomeCheck();
public void DoStuff()
{
// You don't know how DoSomeCheck will be implemented but
// you know a derived class must implement it
DoSomeCheck();
}
}
Alternatively, you use interfaces to define contracts that must be fulfilled by implementers in order to ensure that they can work together with your code:
// This car accepts any engine that implements IEngine
public class Car
{
public IEngine Engine { get; set; }
}
public interface IEngine
{
void Start();
}
There're many other use cases for both abstract classes and interfaces, but covering them would require a to compose a book instead of a simple answer. I still think that above explanation should give you the required hint to learn more about the topic.
can i write abstract class instead of interface here ?
Technically, yes you can. Practically, you shouldn't.
In this particular case implementation of the repositories is likely to be different. If implementation is different, an interface will declare desired behaviour in a clear way. Use of an abstract class can be justified, if the implementation was the same for all your repositories, or some methods where the same. Therefore allowing you to move otherwise duplicated code into one shared place.
In your particular case I'd rather not use either tailored interface or abstract class. There's IEnumerable<T> that does all you want, do not re-invent the wheel:
public class EmployeeRepositoryEF: IEnumerable<Employee> {
...
}
public class EmployeeRepositoryXML: IEnumerable<Employee> {
...
}
whenever you want an array all you need do is ToArray():
EmployeeRepositoryEF myRepo = ...
Employee[] staff = myRepo.ToArray(); // <- just ask for array

Implementing IRepository for multiple domains

I have implemented IRepository interface for multiple domains but I don't know how to call specific method.
Below is the code :
public interface IRepository<T> where T : class
{
IEnumerable<T> GetAll();
void Add(T entity);
void Update(T entity);
}
public interface IProjectRepository : IRepository<ProjectType>, IRepository<Project>, IRepository<ProjectDetail>
{
}
public class ProjectRepository : IProjectRepository
{
// implemenation
}
Now, When I create object of ProjectRepository class it shows all methods of interface but only expecting projecttype parameter.
I don't know, is it correct way of implementation? or Is there another way to implement similar thing?
Generic repository IRepository<T> is not a good solution IMO, take a look at http://www.sapiensworks.com/blog/post/2012/03/05/The-Generic-Repository-Is-An-Anti-Pattern.aspx
I think it's better to specify each repository separately without generic paramter and common methods (are you sure you will always need Add, Update, GetAll in all of your repositories?)
I think it can be better to create Generic repository with Unit of Work pattern.
Take a look at
http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
this is good tutorial about implementation Generic repository with Unit of Work
And at
http://contosontiermvc.codeplex.com/SourceControl/changeset/view/13936#ContosoUniveristy/ContosoUniveristy/Controllers/CourseController.cs
.this is code example

Categories

Resources