we've reached a point where we have no clue how to continue:
SHORT:
We have a generic interface and a collection of the generic interface. Trying to add an implementation of the generic interface to the collection fails. What happens is that I get a compile time exception saying:
cannot convert from TestApp.IState<T>' to TestApp.IState<TestApp.IView>'
LONG [Code example]:
class Program
{
static void Main(string[] args)
{
var coll = new StateCollection();
var state = new SomeState();
coll.AddState(state);
}
}
public class StateCollection
{
private List<StateBase<IView>> _states = new List<StateBase<IView>>();
public void AddState<T>(StateBase<T> state) where T: IView
{
_states.Add(state);
}
}
public class SomeState : StateBase<SomeView>
{
public IView View
{
get;
}
}
public class SomeView : IView
{
}
public abstract class StateBase<T> where T : IView
{
private SomeView _view;
public SomeView View
{
get { return _view; }
}
}
public interface IView
{
}
Why does this happen? In the AddState we mention that T has to be an instance of IState. Could someone help us out with why this happens and how to do what we want to do?
EDIT1:
We also tried:
public void AddState(IState<IView> state)
{
_states.Add(state);
}
But that just moves the compile time error to 'coll.AddState(state)'
So the same thing happens in another place.
EDIT2:
PROBLEM! I didn't give the right example. Out IState is not an interface but an abstract class. Very sorry for that! Changed code to use abstract class
How about these changes:
public class SomeState : IState<SomeView>
{
public SomeView View
{
get;
set;
}
}
Instead of using generic Type T use IView in AddState method
public void AddState(IState<IView> state)
{
_states.Add(state);
}
Make T covariant in IState using out keyword
public interface IState<out T> where T : IView
{
T View { get; }
}
SOLUTION FOR EDIT2:
Don't know if it is ok for you but you can.
public class StateCollection
{
private List<IState<IView>> _states = new List<IState<IView>>();
public void AddState(IState<IView> state)
{
_states.Add(state);
}
}
public class SomeState : StateBase<SomeView>
{
public override SomeView View
{
get { return null; }
}
}
public abstract class StateBase<T> : IState<T> where T : IView
{
public abstract T View { get; }
}
public interface IState<out T> where T : IView
{
T View { get; }
}
First solution
public class StateCollection
{
private readonly List<IState<IView>> _states = new List<IState<IView>>();
public void AddState(IState<IView> state)
{
_states.Add(state);
}
}
as suggested by Nevyn.
To have it to work, mark T as covariant in interface IState<T>
public interface IState<out T> where T:IView
{
IView View { get; }
}
Second solution : (keep change in class StateCollection)
change interface IState<T> to
public interface IState<out T> where T : IView
{
T View { get; }
}
and class SomeState to
public class SomeState : IState<SomeView>
{
public SomeView View{ get;private set; }
}
Solution for Edit2 :
class Program
{
static void Main(string[] args)
{
var coll = new StateCollection();
var state = new SomeState();
coll.AddState(state);
Console.ReadKey();
}
}
public class StateCollection
{
private List<IStateBase<IView>> _states = new List<IStateBase<IView>>();
public void AddState(IStateBase<IView> state)
{
_states.Add(state);
}
}
public class SomeState : StateBase<SomeView>
{
}
public class SomeView : IView
{
}
public interface IStateBase<out T> where T : IView
{
T View { get; }
}
public abstract class StateBase<T> : IStateBase<T> where T : IView
{
public T View { get; set; }
}
public interface IView
{
}
this looks more like a parameter error for the Add function. Have you tried declaring the add function without using the generics? The inheritance itself should allow it. Make the AddState function look like like so:
Edit (as per Edit2):
As mentioned, the inheritance itself should take care of the generics. As long as whatever class you declared properly implements IView, or IState<IView>, then there shouldn't be any issues...
public absract class StateBase
{
public IView view { get; set; }
....
}
public Interface IView
{ ... }
public class StateCollection
{
private List<StateBase> _states = new List<StateBase>();
public void AddState(StateBase state)
{
_states.Add(state);
}
}
public class SomeView : IView
{ ... }
etc etc and so on, as often as needed
public class SomeState : StateBase
{
private SomeView my_view;
public IView view
{
get { return (IView)SomeView; }
set { ; }
}
}
//program remains unchanged
In this case, SomeState is still an IState object, and all IState objects implement IView, and SomeView is an IView object. SomeState implements SomeView internally. Looks the same to me, but I dont know how well the adaption would work with your real code.
Any other classes would follow the same model. The State will implement StateBase, and internally declare a custom View, which itself needs to extend IView. That way the IView cast on the custom view will work.
From comment:
public class BarState : StateBase
{
private BarView my_view;
public IView view
{
get { return (IView)BarView; }
set { ; }
}
}
public class BarView : IView
{ ... }
Add interface IState (non-generic) and inherit it from IState<T>. Then declare _states as List<IState> and method AddState(IState state)
(EDIT: you just need to have your StateBase inherit from the covariant interface. You can't make a class directly covariant, you always have to go through an interface)
Try this:
public class StateCollection
{
private List<IState<IView>> _states = new List<IState<IView>>();
public void AddState(IState<IView> state)
{
_states.Add(state);
}
}
public class SomeState : StateBase<SomeView>
{
}
public class SomeView : IView
{
}
public interface IState<out T> where T : IView // now covariant with T
{
T View { get; }
}
public abstract class StateBase<T> : IState<T> where T : IView
{
public T View { get; set; }
}
public interface IView
{
}
Related
I am trying to achieve a design in c# like below.
void Main()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddScoped(typeof(RedisRepository<>));
serviceCollection.AddScoped(typeof(CommitterBase<IDto>), typeof(ACommitter));
serviceCollection.AddScoped(typeof(CommitterBase<IDto>), typeof(BCommitter));
serviceCollection.AddScoped<Client>();
var services = serviceCollection.BuildServiceProvider();
var client = services.GetRequiredService<Client>();
client.Dump();
}
public class RedisRepository<T> where T: IDto
{
public void Add(T dto)
{
Console.WriteLine("Added data");
}
}
public interface IDto
{
}
public class ADto: IDto
{
}
public class BDto : IDto
{
}
and :
public abstract class CommitterBase<T> where T: IDto
{
public CommitterBase(RedisRepository<T> repo)
{ }
public void Commit()
{
var dto = GenerateDto();
//do something with dto here
}
protected abstract T GenerateDto();
}
and its implementations:
public class ACommitter : CommitterBase<ADto>
{
public ACommitter(RedisRepository<ADto> repo): base(repo)
{ }
protected override ADto GenerateDto()
{
return new ADto();
}
}
public class BCommitter : CommitterBase<BDto>
{
public BCommitter(RedisRepository<BDto> repo) : base(repo)
{
}
protected override BDto GenerateDto()
{
return new BDto();
}
}
public class Client
{
public Client(IEnumerable<CommitterBase<IDto>> committers)
{ }
}
error that I get
Implementation type 'BCommitter' can't be converted to
service type 'UserQuery+CommitterBase`1[IDto]'
I understand from this stackoverflow post that this error is expected. Just wondering how to achieve similar effect without encountering the error. My aim is to extract reusable code into an Abstract Base Class and let the implementations do bare minimum.
Thanks in advance!
Interface cannot be instantiated and IDto is interface. So you can register specific implementation to your interface.
I little bit refactored code to use generic parameters.
This is yor base abstract class:
public abstract class CommitterBase<T> where T : IDto
{
public CommitterBase(RedisRepository<T> repo)
{ }
public void Commit()
{
var dto = GenerateDto();
//do something with dto here
}
protected abstract T GenerateDto();
}
And its concrete implementations such as ACommitter:
public class ACommitter<T> : CommitterBase<T> where T : IDto, new()
{
public ACommitter(RedisRepository<T> repo) : base(repo)
{ }
protected override T GenerateDto()
{
return new T();
}
}
and BCommitter:
public class BCommitter<T> : CommitterBase<T> where T: IDto, new()
{
public T FooBar { get; set; }
public BCommitter(RedisRepository<T> repo) : base(repo)
{
}
protected override T GenerateDto()
{
return new T();
}
}
and RedisRepository:
public class RedisRepository<T> where T : IDto
{
public void Add(T dto)
{
Console.WriteLine("Added data");
}
}
and Client class:
public class Client<T> where T : IDto, new()
{
public CommitterBase<T> CommitterBaseProperty { get; set; }
public Client(CommitterBase<T> committer) // if you want all instances of committers,
// then you need to create a factory
// and inject it through DI
{
CommitterBaseProperty = committer;
}
}
And you can call it like this:
static void Main(string[] args)
{
ServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddScoped<RedisRepository<ADto>>();
serviceCollection.AddScoped<RedisRepository<BDto>>();
serviceCollection.AddScoped<CommitterBase<ADto>, ACommitter<ADto>>();
serviceCollection.AddScoped<CommitterBase<BDto>, BCommitter<BDto>>();
serviceCollection.AddScoped<Client<ADto>>();
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
CommitterBase<ADto> committerBase = serviceProvider.GetRequiredService<CommitterBase<ADto>>();
CommitterBase<BDto> committerBase_B =
serviceProvider.GetRequiredService<CommitterBase<BDto>>();
committerBase.Commit();
Client<ADto> client = serviceProvider.GetRequiredService<Client<ADto>>();
}
How to use dependency injection for generic interfaces? I want the IDrawView interface to be created in DrawPresenter, and it controls the view.
I do not know what to use, Ninject or something else. I am using WinForms.
Which is better to choose?
class Program
{
static void Main(string[] args)
{
IDrawPresenter prisenter = new DrawPresenter(new DrawWindow());
prisenter.Show();
Console.ReadLine();
}
}
public interface IView
{
void Show();
}
public interface IDrawView : IView
{
object GetGridDraw { get; }
}
public interface IPrisenter<TView> where TView : IView
{
void Show();
}
public interface IDrawPresenter : IPrisenter<IDrawView>
{
object SelectedDraws { get; }
}
public class DrawWindow : IDrawView
{
public object GetGridDraw => 1;
public void Show()
{
Console.WriteLine("Show Window");
}
}
public abstract class BasePresenter<TView> : IPrisenter<TView>
where TView : IView
{
protected BasePresenter(TView view)
{
View = view;
}
protected TView View { get; private set; }
public void Show()
{
View.Show();
}
}
public class DrawPresenter : BasePresenter<IDrawView>, IDrawPresenter
{
public DrawPresenter(IDrawView view): base(view)
{
}
public object SelectedDraws => View.GetGridDraw;
}
Can DI implement this?
IDrawPresenter prisenter = new DrawPresenter();
public DrawPresenter()
{
}
What I need to do for Presenter to manage the form.
Here is what I want to get. But this does not work ...
public class NinjectProgram
{
//Gets the inject kernal for the program.
public static IKernel Kernel { get; protected set; }
}
public class DependencyModule : NinjectModule
{
public override void Load()
{
Bind<IDrawView>().To<DrawWindow>();
}
}
static void Main(string[] args)
{
StandardKernel Kernel = new StandardKernel();
Kernel.Load(new DependencyModule());
IDrawPresenter prisenter = new DrawPresenter();
prisenter.Show();
Console.ReadLine();
}
public abstract class BasePresenter<TView> : IPrisenter<TView>
where TView : IView
{
protected BasePresenter()
{
View = NinjectProgram.Kernel.Get<TView>();
}
protected TView View { get; private set; }
public void Show()
{
View.Show();
}
}
Thank you all, that’s what I wanted to do. Perhaps this will help someone in the future.
static void Main(string[] args)
{
CompositionRoot.Wire(new DependencyModule());
IDrawPresenter prisenter = new DrawPresenter();//kernel.Get<IDrawPresenter>();
prisenter.Show();
Console.ReadLine();
}
public class CompositionRoot
{
private static IKernel _ninjectKernel;
public static void Wire(INinjectModule module)
{
_ninjectKernel = new StandardKernel(module);
}
public static T Resolve<T>()
{
return _ninjectKernel.Get<T>();
}
}
public class DependencyModule : NinjectModule
{
public override void Load()
{
Bind<IDrawView>().To<DrawWindow>();
}
}
public abstract class BasePresenter<TView> : IPrisenter<TView>
where TView : IView
{
protected BasePresenter()
{
View = CompositionRoot.Resolve<TView>();//NinjectProgram.Kernel.Get<TView>();
}
protected TView View { get; private set; }
}
Also include the presenter in the container and resolve it.
public class DependencyModule : NinjectModule {
public override void Load() {
Bind<IDrawView>().To<DrawWindow>();
Bind<IDrawPresenter>().To<DrawPresenter>();
}
}
All its dependencies, if registered, will also be resolved and injected into the presenter
static void Main(string[] args) {
var kernel = new StandardKernel();
kernel.Load(new DependencyModule());
IDrawPresenter presenter= kernel.Get<IDrawPresenter>();
presenter.Show();
Console.ReadLine();
}
The above is based on
public abstract class BasePresenter<TView> : IPrisenter<TView> where TView : IView {
protected BasePresenter(TView view) {
View = view;
}
protected TView View { get; private set; }
public void Show() {
View.Show();
}
}
public class DrawPresenter : BasePresenter<IDrawView>, IDrawPresenter {
public DrawPresenter(IDrawView view): base(view) {
}
public object SelectedDraws => View.GetGridDraw;
}
Consider the following interface and class declarations.
public interface IMessage
{
string Body { get; set; }
}
public abstract class MessageBase : IMessage
{
public string Body { get; set; }
}
public class MessageA : MessageBase { }
public class MessageB : MessageBase { }
public class MessageC : MessageBase { }
public interface IMessageProcessor<T> where T : IMessage
{
Action<T> ProcessorAction { get; set; }
}
public abstract class MessageProcessorBase<T> : IMessageProcessor<T> where T : MessageBase
{
public Action<T> ProcessorAction { get; set; }
}
public class MessageAProcessor : MessageProcessorBase<MessageA> { }
public class MessageBProcessor : MessageProcessorBase<MessageB> { }
public class MessageCProcessor : MessageProcessorBase<MessageC> { }
Now I want to declare a list of processor instances like so, but cannot figure out what generic type will allow me to add any derived processor type to the list.
var processors = new List<???>();
processors.Add(new MessageAProcessor());
processors.Add(new MessageBProcessor());
processors.Add(new MessageCProcessor());
I have tried:
// compiles but throws InvalidCastException
var processors = new List<IMessageProcessor<IMessage>>();
processors.Add((IMessageProcessor<IMessage>)new MessageAProcessor());
and
// compiles but throws InvalidCastException
var processors = new List<IMessageProcessor<MessageBase>>();
processors.Add((IMessageProcessor<MessageBase>)new MessageAProcessor());
and
// won't compile
var processors = new List<MessageProcessorBase<MessageBase>>();
processors.Add((MessageProcessorBase<MessageBase>)new MessageAProcessor());
What should the type of this list be? I know I must be missing something obvious here. Any help here would be greatly appreciated. Thanks!
You need to introduce IMessageProcessor and inherit all your Processors from it. In list you would have to use this interface.
public interface IMessage {
string Body { get; set; }
}
public abstract class MessageBase : IMessage {
public string Body { get; set; }
}
public class MessageA : MessageBase {
}
public class MessageB : MessageBase {
}
public class MessageC : MessageBase {
}
public interface IMessageProcessor<T> where T : IMessage {
Action<T> ProcessorAction { get; set; }
}
public abstract class MessageProcessorBase<T> : IMessageProcessor<T> where T : MessageBase {
public Action<T> ProcessorAction { get; set; }
public void ProcessMessage(IMessage message) {
var msg = message as T;
ProcessorAction(msg);
}
}
public interface IMessageProcessor {
void ProcessMessage(IMessage message);
}
public class MessageAProcessor : MessageProcessorBase<MessageA>,IMessageProcessor {
}
public class MessageBProcessor : MessageProcessorBase<MessageB>,IMessageProcessor {
}
public class MessageCProcessor : MessageProcessorBase<MessageC>,IMessageProcessor {
}
And Processors:
var processors = new List<IMessageProcessor>();
processors.Add(new MessageAProcessor());
processors.Add(new MessageBProcessor());
processors.Add(new MessageCProcessor());
Since there is no inheritance relationship between ISomething<Type1> and ISomething<Type2> you can't have list of objects that contain mix of those types.
Only real option is to force some base type - either use List<object> or better have base non-generic interface for IMessageProcessor<T> like IMessageProcessor<T> : IMessageProcessor.
Unfortunately it also means you can't have access to properties/arguments using generic type without casts.
I'm not sure what you are trying to accomplish, but your code will indeed not work.
I did the following:
public class MessageAProcessor : MessageProcessorBase<MessageBase> { }
public class MessageBProcessor : MessageProcessorBase<MessageBase> { }
public class MessageCProcessor : MessageProcessorBase<MessageBase> { }
And then:
var processors = new List<MessageProcessorBase<MessageBase>> ();
processors.Add(new MessageAProcessor());
processors.Add(new MessageBProcessor());
processors.Add(new MessageCProcessor());
will work.
The problem is that
public class MessageAProcessor : MessageProcessorBase<MessageA> { }
is too specific, and you can't cast this back to MessageProcessorBase<MessageBase> in the List<>.
I have a Base class which is generic.
I have a concrete class which implements the base class.
How would I create a factory class/method for delivering different types of concrete classes?
Here an example:
public class ReceiverBase<T>
where T : IInterpreter
{ ... }
public class SpecialReceiver : ReceiverBase<OwnInterpreter> { ... }
public class ReceiverFactory<T>
where T : ReceiverBase<IInterpreter>, new()
public T Create(string type) {
switch(type) {
default:
return new SpecialReceiver();
}
}
}
The problem is that ReceiverBase seems not to be possible because the compiler only wants classes as Constraints, not interfaces.
And the second problem is that I cannot convert SpecialReceiver to T.
So is there a way to get this working?
=== EDIT: Added example according to first answer ===
public interface IInterpreter
{
}
public class OwnInterpreter : IInterpreter
{
public void Dispose()
{
throw new NotImplementedException();
}
public void DoSomething() { }
}
public abstract class ReceiverBase<T>
where T : IInterpreter
{
public T MyReceiver { get; set; }
internal abstract void Start();
}
public class SpecialReceiver<T> : ReceiverBase<T>
where T : IInterpreter, new()
{
public void CheckSomething()
{
MyReceiver.DoSomething();
}
internal override void Start()
{
MyReceiver = new T();
}
}
public class ReceiverFactory<T>
where T : IInterpreter, new()
{
public static ReceiverBase<T> Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver<T>();
}
}
}
The Problem is: MyReceiver.DoSomething(); will not work.
Additionally I would have to call the factory like this: ReceiverFactory<OwnInterpreter>.Create(""); I'd like to have it that way: ReceiverFactory.Create("SpecialReceiver");
You can use generic method in your factory:
class Program
{
static void Main(string[] args)
{
var own = ReceiverFactory.Create<OwnInterpreter>();
var other = ReceiverFactory.Create<OtherInterpreter>();
own.Start();
other.Start();
Console.ReadLine();
}
}
interface IInterpreter
{
void DoSomething();
}
class OwnInterpreter : IInterpreter
{
public void DoSomething() { Console.WriteLine("Own"); }
}
class OtherInterpreter : IInterpreter
{
public void DoSomething() { Console.WriteLine("Other"); }
}
abstract class ReceiverBase<T> where T: IInterpreter, new()
{
public T Interpreter { get; set; }
public ReceiverBase()
{
Interpreter = new T();
}
public void Start()
{
Interpreter.DoSomething();
}
}
class SpecialReceiver : ReceiverBase<OwnInterpreter> { }
class OtherReceiver : ReceiverBase<OtherInterpreter> { }
static class ReceiverFactory
{
private static Dictionary<string, object> factories = new Dictionary<string, object>();
static ReceiverFactory()
{
RegisterFactory(() => new SpecialReceiver());
RegisterFactory(() => new OtherReceiver());
}
public static void RegisterFactory<T>(Func<ReceiverBase<T>> factory) where T : IInterpreter, new()
{
factories.Add(typeof(T).FullName, factory);
}
public static ReceiverBase<T> Create<T>() where T : IInterpreter, new()
{
var type = typeof(T);
return ((Func<ReceiverBase<T>>)factories[type.FullName]).Invoke();
}
}
In fact, you do not need "new()" constraint here, since you use factories.
I suggest you to change your code to:
public class ReceiverBase<T> where T : IInterpreter
{
}
public interface IInterpreter
{
}
public class SpecialReceiver<T> : ReceiverBase<T>
where T : IInterpreter
{
}
public class OwnInterpreter : IInterpreter
{
}
public class ReceiverFactory<T> where T : IInterpreter, new()
{
public ReceiverBase<T> Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver<T>();
}
}
}
The reason why you cannot just return T in your case is, that there is no implicit conversion between SpecialReceiver and ReceiverBase<IInterpreter>.
I was able to find a solution which suits my needs.
I've added another interface IReciver which defines the properties and members I really need. The factory method returns IReceiver so I can omit all binding issues whith generics. Sometimes it is just that easy. :)
public interface IInterpreter { }
public interface IReceiver
{
bool Enabled { get; set; }
}
public class OwnInterpreter : IInterpreter
{
public void DoSomething() { }
}
public abstract class ReceiverBase<T> : IReceiver
where T : IInterpreter, new()
{
public T MyReceiver { get; set; }
internal abstract void Start();
private bool _isEnabled;
public bool Enabled { get { return _isEnabled; } set { _isEnabled = value; OnEnable(value); } }
internal abstract void OnEnable(bool isEnabled);
protected ReceiverBase()
{
MyReceiver = new T();
}
}
public class SpecialReceiver : ReceiverBase<OwnInterpreter>
{
public void CheckSomething()
{
MyReceiver.DoSomething();
}
internal override void Start()
{
// just for testing puropses
MyReceiver = new OwnInterpreter();
}
internal override void OnEnable(bool isEnabled)
{
MyReceiver = isEnabled ? new OwnInterpreter() : null;
}
}
public class ReceiverFactory
{
public static IReceiver Create(string type)
{
switch (type)
{
default:
return new SpecialReceiver();
}
}
}
public class Program
{
[STAThread]
public static void Main()
{
ReceiverFactory.Create("");
}
}
I have a the following C# classes and interfaces:
class NativeTool
class NativeWidget: NativeTool
class NativeGadget: NativeTool
// above classes defined by the API I am using. Below classes and interfaces defined by me.
interface ITool
interface IWidget: ITool
interface IGadget: ITool
class MyTool: NativeTool, ITool
class MyWidget: NativeWidget, IWidget
class MyGadget: NativeGadget, IGadget
Now, I would like MyTool to keep a list of children. The children will all conform to ITool and inherit from NativeTool. The classes MyTool, MyWidget, and MyGadget all fit these criteria.
My question is, is there any way to tell MyTool that its children will always inherit from both NativeTool and ITool? I can do one or the other easily enough. But both?
You may do something like:
public class MyTool<T,U> where T: ITool where U: NativeTool
{
}
and create this like:
var tool = new MyTool<MyWidget, MyWidget>();
and also derivates, like
public class MyWidget : MyTool<....>
{
}
This appears to do it. An annoying number of wrappers, but it gets the job done, without duplicating storage.
public interface ITool { }
public interface IWidget : ITool { }
public class NativeTool { }
public class NativeWidget : NativeTool { }
public class MyTool : NativeTool, ITool, INativeTool {
public MyTool() {
this.Children = new List<INativeTool>();
}
public ITool InterfacePayload { get { return this; } }
public NativeTool NativePayload { get { return this; } }
public List<INativeTool> Children { get; set; }
public NativeTool NativeChild(int index) {
return this.Children[index].NativePayload;
}
public ITool InterfaceChild(int index) {
return this.Children[index].InterfacePayload;
}
public void AddChild(MyTool child) {
this.Children.Add(child);
}
public void AddChild(MyWidget child) {
this.Children.Add(child);
}
}
public class MyWidget : NativeWidget, IWidget, INativeTool {
public ITool InterfacePayload { get { return this; } }
public NativeTool NativePayload { get { return this; } }
}
public interface INativeTool {
// the two payloads are expected to be the same object. However, the interface cannot enforce this.
NativeTool NativePayload { get; }
ITool InterfacePayload { get; }
}
public class ToolChild<TPayload>: INativeTool where TPayload : NativeTool, ITool, INativeTool {
public TPayload Payload { get; set; }
public NativeTool NativePayload {
get {return this.Payload;}
}
public ITool InterfacePayload {
get { return this.Payload; }
}
}