How to use dependency injection for generic interfaces? - c#

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;
}

Related

Extract Reusable Code into Abstract Base Class with Generic Parameters

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>>();
}

Lazy decorator - The lazily-initialized type does not have a public, parameterless constructor

I cant make working the code below.. Do I need other class that impolement my IComponent with paratmeterless consturctor?
public class Program
{
public static void Main()
{
var lazy = new Lazy<IComponent>();
IComponent comp = lazy.Value;
var client = new ComponentClient(comp);
client.Run();
}
}
public interface IComponent
{
void Something();
}
public class LazyComponent : IComponent
{
public Lazy<IComponent> _LazyComponent { get; set ;}
public LazyComponent(Lazy<IComponent> lazyComponent)
{
_LazyComponent = lazyComponent;
}
public void Something()
{
_LazyComponent.Value.Something();
}
}
public class ComponentClient
{
public IComponent _Component { get; set; }
public ComponentClient(IComponent component)
{
_Component = component;
}
public void Run()
{
_Component.Something();
}
}
You need to tell the Lazy how to construct the component, by giving it a factory method.
https://learn.microsoft.com/en-us/dotnet/api/system.lazy-1?view=netframework-4.8
public class Program
{
public static void Main()
{
var lazy = new Lazy<IComponent>(() => new RealComponent());
var lazyComponent = new LazyComponent(lazy);
var client = new ComponentClient(lazyComponent);
client.Run();
}
}

WPF Modular Initialization after Package Update

Hi hope you guys can help me.
I Inherited a Project and needed to Update the Packages and there was a Change in the Initialization.
public abstract class ModuleBase : Prism.Modularity.IModule
{
public IUnityContainer UnityContainer { get; private set; }
public IRegionManager RegionManager { get; private set; }
public ModuleBase(IUnityContainer unityContainer, IRegionManager regionManager)
{
if (unityContainer == null)
{
throw new ArgumentNullException("unityContainer");
}
UnityContainer = unityContainer;
if (regionManager == null)
{
throw new ArgumentNullException("regionManager");
}
RegionManager = regionManager;
}
public virtual void Initialize() { }//old
public abstract void RegisterTypes(IContainerRegistry containerRegistry);//new
public abstract void OnInitialized(IContainerProvider containerProvider);//new
}
I have this Base and from there Extended are the different Modules.
public class UserModule : ModuleBase
{
public UserModule(IUnityContainer unityContainer, IRegionManager regionManager)
: base(unityContainer, regionManager)
{
}
public override void Initialize()//old
{
UnityContainer.RegisterType<UserView>();
UnityContainer.RegisterType<UserKernelSettingsView>();
UnityContainer.RegisterType<UserNavigationItemView>();
UnityContainer.RegisterTypeForNavigation<UserView>();
UnityContainer.RegisterTypeForNavigation<UserKernelSettingsView>();
RegionManager.RegisterViewWithRegion(RegionNames.NavigationRegion, typeof(UserNavigationItemView));
}
public override void OnInitialized(IContainerProvider containerProvider)//new
{
}
public override void RegisterTypes(IContainerRegistry containerRegistry)//new
{
}
}
But now i am not able to Register the Views correct.
BR MAX
Try this:
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve<IRegionManager>();
regionManager.RegisterViewWithRegion(RegionNames.NavigationRegion, typeof(UserNavigationItemView));
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<UserView>();
containerRegistry.Register<UserKernelSettingsView>();
containerRegistry.Register<UserNavigationItemView>();
containerRegistry.RegisterForNavigation<UserView>();
containerRegistry.RegisterForNavigation<UserKernelSettingsView>();
}

Head First design pattern program in C# -getting Duck.quackableDuck is inaccessible

I am getting runtime error Duck.quackableDuck and Duck.flyableDuck is inaccessible.
I have created two interfaces FlyableDuck and QuackableDuck. Class MallardDuck is inherited from class Duck.
using System;
//creating interfaces
public interface FlyableDuck
{
void fly();
}
public interface QuackableDuck
{
void quack();
}
//creating behavior classes
public class FlyWithWings:FlyableDuck
{
public void fly()
{
Console.WriteLine("I am flying.");
}
}
public class FlyNoWings: FlyableDuck
{
public void fly()
{
Console.WriteLine("I can't fly. :(");
}
}
public class Quacking: QuackableDuck
{
public void quack()
{
Console.WriteLine("Quack Quack!!");
}
}
public class NoQuack : QuackableDuck
{
public void quack()
{
Console.WriteLine("Can't quack :(");
}
}
public class SqueakQuack : QuackableDuck
{
public void quack()
{
Console.WriteLine("Squeak quack!!");
}
}
//creating abstrack class
public abstract class Duck
{
QuackableDuck quackableDuck;
FlyableDuck flyableDuck;
public Duck() { }
public abstract void display();
public void perfomFly()
{
flyableDuck.fly();
}
public void perfomQuack()
{
quackableDuck.quack();
}
public void swim()
{
Console.WriteLine("All ducks swim :)");
}
}
//subclass
public class MallardDuck:Duck
{
public MallardDuck()
{
quackableDuck = new Quacking();
flyableDuck = new FlyWithWings();
}
public override void display()
{
Console.WriteLine("I am Mallard Duck.");
}
}
public class Class2
{
public static void Main(String[] args)
{
MallardDuck mallard = new MallardDuck();
mallard.perfomFly();
mallard.perfomQuack();
Console.ReadKey();
}
}
These 2:
QuackableDuck quackableDuck;
FlyableDuck flyableDuck;
Are private (by default) so change it to:
public QuackableDuck quackableDuck;
public FlyableDuck flyableDuck;
You can also use protected/internal instead of public

c# Factory for concrete implementation of generic base class

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("");
}
}

Categories