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>();
}
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>>();
}
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();
}
}
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;
}
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
First time using MS Unity. I have a controller with the following constructor:
protected IAdministrationService AdministrationService { get; set; }
public GenerateCacheController(IAdministrationService administrationService)
{
AdministrationService = administrationService;
}
I get the following error when trying to run the project:
Make sure that the controller has a parameterless public constructor.
In my Bootstrpper.cs file I have the following in the RegisterTypes method:
container.RegisterType<GenerateCacheController>();
I still get the error. Am I missing anything else? I'm using ASP.NET MVC 5 and Unity 3.
Here's my Boostrapper.cs file:
public static class Bootstrapper
{
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
}
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterInstance(container);
var im = new InjectionMember[0];
container.RegisterType<IAdministrationService, AdministrationService>("AdministrationService", im);
container.RegisterType<ILookupMapper, LookupMapper>("LookupMapper", im);
container.RegisterType<IEmailService, EmailService>("EmailService", im);
container.RegisterType<GenerateCacheController>();
var provider = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => provider);
}
}
Abbreviated version of the AdministrationService class:
public class AdministrationService : IAdministrationService
{
protected ILookupMapper LookupMapper { get; set; }
protected IEmailService EmailService { get; set; }
public AdministrationService(ILookupMapper lookupMapper, IEmailService emailService)
{
LookupMapper = lookupMapper;
EmailService = emailService;
}
}
Found the issue.
I commented out the line:
var im = new InjectionMember[0];
container.RegisterType<IAdministrationService, AdministrationService>("AdministrationService", im);
and added:
container.RegisterType<IAdministrationService, AdministrationService>();
And that worked because the previous developers were doing something like this:
private IUnityContainer Container { get; set; }
public AdministrationService()
{
Container = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IUnityContainer>();
}
instead of
protected ILookupMapper LookupMapper { get; set; }
protected IEmailService EmailService { get; set; }
public AdministrationService(ILookupMapper lookupMapper, IEmailService emailService)
{
LookupMapper = lookupMapper;
EmailService = emailService;
}
I have to go back to their way to not break existing code. I'll get around to refactoring one day.