I am having a problem. Lets see an example: you got this interface which would be implemented by Employee.cs and Owener.cs:
public interface IEmployee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
}
public class Employee: IEmployee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
}
public class Owner: IEmployee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
public string Status{ get; set; } <--- //problem string
}
Now when we are using Dependency Injection and it returns the object of employee or manager, thats where i run into problem.
public class EmployeeCheck{
private IEmployee empObj;
public EmployeeCheck(IEmployee _em)
{
empObj=_em
}
public void PrintCheck()
{
string str=_em.FirstName;
string str2=(Owner)_emp.Status <--- //problem...how do I access it?? It can't be accessed cause
//IEMployee doesn't have status field!
}
So basically if I use IEmployee as the interface , I can't access fields in new the Owner class, and if I do put them in interface, then Employee class which doesn't need to implement it, will be forced to implement something it doesn't need! And I do need IEmployee due to DI injection or other design pattern
OK, I can't use abstract class...so lets discuss more about the IStatus solution...so you are talking about writing code like this:
public interface IStatus:IEmployee
{
public string Title { get; set; }
}
public class Owner: IEmployee, IStatus { public string FirstName { get; set; }
public string LastName { get; set; }
public string Location { get; set; }
public string Status{ get; set; } <--- //problem string
}
But how do I work it in Employee check class?
public class EmployeeCheck {
private IEmployee empObj;
public EmployeeCheck(IEmployee _em, IStatus)
{
empObj=_em
}
}
The scenario that you're dealing with could be handled traditionally using IoC Containers
like StructureMap or Unity by using something called Named Instances. These containers provide this kind of functionality out of the box.
The same can be achieved in .NET Core
in multiple ways. One way is to use the extension method from IServiceCollection
. The below snippet walks you through how this could be done in your scenario
// using Microsoft.Extensions.DependencyInjection
// Startup.cs - ConfigureServices()
services.AddTransient(serviceProvider =>
{
Func<string, IMyClass> func = key =>
{
switch (key)
{
case "MyClass":
return serviceProvider.GetService<MyClass>();
case "MyClass1":
return serviceProvider.GetService<MyClass2>();
default:
throw new KeyNotFoundException();
}
};
return func;
});
//Register your services here as usual
services.AddTransient<IMyClass, MyClass>();
services.AddTransient<IMyClass, MyClass2>();
You are essentially creating a factory here that is going to give out the dependency of the type that you need based on the key
. The following snippet of code shows how this can be done within your controller.
// ctor of your controller
public MyController(Func<string, IMyClass> injector)
{
// key here could be 'MyClass' or 'MyClass2'
IMyClass service = injector("<key>");
}
Below is the structure of sample classes I have considered for the above sample
// implementation 1
public class MyClass : IMyClass
{
}
// implementation 2
public class MyClass2 : IMyClass
{
}
// interface
public interface IMyClass
{
}
There are also other ways to handle this. You can take a look at this answer for other approaches.