C# Ninject: How to inject dependency depending on field? - c#

A class named Round is a level design in a adventure game.Its filed number indicate which level the player is in. Different level will have different figures to guess. The figures are produced by field FigureFactory.
The question is: using Ninject for dependency injection, how can I set the cooresponding FigureFactory to the variable round, according to the field number? For instance, when field number==1, the cooresponding factory is FigureFactory1, when field number==2, the cooresponding factory is FigureFactory2?
using GuessFigure.Model.Factory;
using Ninject;
using Ninject.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ninject.Planning.Bindings;
namespace GuessFigure.Model
{
class Round
{
private int number=1;
private FigureFactory figureFactory;
[Inject]
internal void SetFigureFactory(FigureFactory figureFactory)
{
this.figureFactory = figureFactory;
}
public int[] GetCurrentRoundFigures()
{
return figureFactory.Produce(number);
}
}
//this not work, help please
class RoundModule : NinjectModule
{
public override void Load()
{
Bind<FigureFactory>().To<FigureFactoryRound1>().When(request=>request.ParentRequest.Target.Type.GetField("number").Equals(1));
Bind<FigureFactory>().To<FigureFactoryRound2>().When(request => request.Target.Type.GetField("number").Equals(2));
Bind<FigureFactory>().To<FigureFactoryRound3>().When(request => request.Target.Type.GetField("number").Equals(3));
Bind<FigureFactory>().To<FigureFactoryRound4>().When(request => request.Target.Type.GetField("number").Equals(4));
Bind<FigureFactory>().To<FigureFactoryRound5>().When(request => request.Target.Type.GetField("number").Equals(5));
}
}
}
Factory Method Pattern implementation:
using System;
namespace GuessFigure.Model
{
abstract class FigureFactory
{
protected int figureNumber;
public FigureFactory(int figureNumber)
{
this.figureNumber = figureNumber;
}
internal int[] Produce()
{
int[] figureArray = new int[figureNumber];
for (int i = 0; i < figureNumber; i++)
{
figureArray[i] = Algorithm(i + 1);
}
return figureArray;
}
abstract protected int Algorithm(int inputNumber);
}
}
Concrete Factory(there are still some like this);
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuessFigure.Model
{
class FigureFactoryRound1 : FigureFactory
{
public FigureFactoryRound1(int figureNumber) : base(figureNumber)
{
}
protected override int Algorithm(int inputNumber)
{
return inputNumber;
}
}
}
class FigureFactoryRound3 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuessFigure.Model.Factory
{
class FigureFactoryRound3 : FigureFactory
{
public FigureFactoryRound3(int figureNumber) : base(figureNumber)
{
}
protected override int Algorithm(int inputNumber)
{
return (int) Math.Pow( inputNumber,2) ;
}
}
}
class FigureFactoryRound4 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuessFigure.Model.Factory
{
class FigureFactoryRound4 : FigureFactory
{
public FigureFactoryRound4(int figureNumber) : base(figureNumber)
{
}
protected override int Algorithm(int inputNumber)
{
return (int)Math.Pow(inputNumber, 3);
}
}
}
Usage:
IKernel kernel = new StandardKernel(new RoundModule());
Round round = new Model.Round();
round.SetFigureFactory(kernel.Get<FigureFactory>());
int[] array=round.GetCurrentRoundFigures();

Related

Create an instance of a class from another package

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace assign_5.model
{
class Person
{
public void t()
{
Console.WriteLine("try");
}
public string h()
{
return "ll";
}
}
}
using assign_5.model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace assign_5.Controller
{
class FirstNameController
{
Person p = new Person();
p.t();
string o = p.h();
}}
Why there is an error in p.t(); and string o = p.h();
"Error CS0236 A field initializer cannot reference the non-static field, method, or property 'FirstNameController.p' assign_5 "
You need move your code to a method in class, also make class Person as public to accessable from another namespace as
public class Person{}
class FirstNameController
{
void test(){
Person p = new Person();
p.t();
string o = p.h();
}
}

Change button background image using method in Winforms

My code for Form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace YAHTZEE
{
public partial class GameMainWindow : Form
{
public GameMainWindow()
{
InitializeComponent();
}
private void buttonRollDice_Click(object sender, EventArgs e)
{
DiceManager dm = new DiceManager();
dm.intDice_1_Roll();
dm.intDice_2_Roll();
dm.intDice_3_Roll();
dm.intDice_4_Roll();
dm.intDice_5_Roll();
Class1 c1 = new Class1();
c1.buttonDice_1Manager();
}
}
}
My class for generating random number for all the dice.
This works perfectly fine.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace YAHTZEE
{
public class DiceManager
{
Random rnd = new Random();
public int intDice_1_Roll()
{
int intDice_1 = rnd.Next(1, 7);
return intDice_1;
}
public int intDice_2_Roll()
{
int intDice_2 = rnd.Next(1, 7);
return intDice_2;
}
public int intDice_3_Roll()
{
int intDice_3 = rnd.Next(1, 7);
return intDice_3;
}
public int intDice_4_Roll()
{
int intDice_4 = rnd.Next(1, 7);
return intDice_4;
}
public int intDice_5_Roll()
{
int intDice_5 = rnd.Next(1, 7);
return intDice_5;
}
}
}
Class to change button background image.
This is where my problem is, the code works if I put it on my form but it does nothing when I make it a method on another class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YAHTZEE.Properties;
namespace YAHTZEE
{
class Class1 : GameMainWindow
{
public void buttonDice_1Manager()
{
DiceManager dm = new DiceManager();
if (dm.intDice_1_Roll() == 1)
{
buttonDice_1.BackgroundImage = Properties.Resources.Dice1;
}
}
}
}
Am I missing something?
P.S. I want them to be separated because there are a lot of things to consider making my code very long.
In class1, try changing your method to:
public System.Drawing.Bitmap dice1Manager(int diceRoll)
{
if(diceRoll == 1)
return Properties.Resources.Dice1;
}
In your main class, change what you have to:
private void buttonRollDice_Click(object sender, EventArgs e)
{
DiceManager dm = new DiceManager();
Class1 c1 = new Class1();
button_dice1.BackgroundImage = c1.dice1Manager(dm.intDice_1_Roll());
dm.intDice_2_Roll();
dm.intDice_3_Roll();
dm.intDice_4_Roll();
dm.intDice_5_Roll();
}

WCF with Duplex Communication

Whenever I am using Window Forms It works Fine But it always give error with console applicion.
Error- The socket connection was aborted. This could be caused by an
error processing your message or a receive timeout being exceeded by
the remote host, or an underlying network resource issue. Local socket
timeout was '00:01:00'.
Here is My Code
Contract
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace ClassLibrary1
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IReportService" in both code and config file together.
[ServiceContract(CallbackContract=typeof(IReportServiceCallbak))]
public interface IReportService
{
[OperationContract(IsOneWay=true)]
void ProcessReport();
}
public interface IReportServiceCallbak
{
[OperationContract(IsOneWay=true)]
void Progress(int percentage);
}
}
Service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading;
namespace ClassLibrary1
{
public class ReportService : IReportService
{
public void ProcessReport()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(50);
OperationContext.Current.GetCallbackChannel<IReportServiceCallbak>().Progress(i);
}
}
}
}
Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Threading.Tasks;
using System.Threading;
namespace DuplexClientsss
{
class Program
{
static void Main(string[] args)
{
new Tests();
} }
class Tests : ReportService.IReportServiceCallback
{
ReportService.ReportServiceClient obj;
public Tests()
{
obj = new ReportService.ReportServiceClient(new InstanceContext(this));
obj.ProcessReport();
}
public void Progress(int percentage)
{
Console.WriteLine(percentage);
}
}
}
new Task
(
()=>
{
obj.ProcessReport();
}
).Start();

NSubstitute Checking received calls don't work

Hey guys im new with the NSubstitute framework. I'm trying to test some of my classes, but when i use NSubstitute to check received calls it says received no matching calls.
I'm trying to test if the method Tick() is receiving update() from track class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ATM_System.Event;
using ATM_System.EventDetection;
using ATM_System.Region;
using ATM_System.Track;
namespace ATM_System
{
public class ATM
{
private List<ITrack> _tracks;
private IRegion _region;
private List<IEventDetection> _eventdetects;
private List<IEvent> _events;
public ATM()
{
_tracks = new List<ITrack>();
_region = new Region.Region(100000,100000); //could be changed by user
_events = new List<IEvent>();
_eventdetects = new List<IEventDetection>();
}
public void Tick()
{
// update track positions
foreach (var track1 in _tracks)
{
track1.update();
}
//check for events
foreach (var detector in _eventdetects)
{
_events.AddRange(detector.DetectEvent(_tracks));
}
//handle events and output
foreach (var event1 in _events)
{
event1.HandleEvent();
event1.LogEvent();
}
}
public void IncomingTrack(ITrack track)
{
//add incoming track
_tracks.Add(track);
}
}
}
TEST FILE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ATM_System.Event;
using ATM_System.EventDetection;
using ATM_System.Track;
using NUnit.Framework;
using NSubstitute;
namespace ATM_System.Tests.Unit
{
[TestFixture]
class ATMUnitTests
{
private ATM _uut;
private ITrack _track;
private IEvent _event;
private IEventDetection _eventDetection;
[SetUp]
public void Setup()
{
_track = Substitute.For<ITrack>();
_event = Substitute.For<IEvent>();
_eventDetection = Substitute.For<IEventDetection>();
_uut = new ATM();
}
[Test]
public void Tick_UpdateTracks_TracksUpdated()
{
_uut.Tick();
_track.Received().update();
}
}
}
You forgot to include _track in notification receivers. It simply hasn't subscribed to event and as a result is not notified. To fix simply call your IncomingTrack method:
[Test]
public void Tick_UpdateTracks_TracksUpdated()
{
_uut.IncomingTrack(_track);
_uut.Tick();
_track.Received().update();
}

Current Context error

I am having trouble calling out Method Globals.Global.InstantiateBlowerObj(); in public frmMain(). I am getting the error "The name 'Globals.Global.InstantiateBlowerObj' does not exist in the current context." I have all the classes and methods as public and I cant figure this out.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WetVacClient;
using Globals;
using Globals.Global;
namespace Globals
{
public class Global
{
public Blower[] _Blower = new Blower[4];
public void InstantiateBlowerObj()
{
for (int i = 1; i < 4; i++)
_Blower[i] = new Blower(i);
}
}
}
namespace WetVacClient
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
Globals.Global.InstantiateBlowerObj();
}
}
}
You need to make both the method and _Blower Property Static
public static Blower[] _Blower = new Blower[4];
public static void InstantiateBlowerObj()
{
for (int i = 1; i < 4; i++)
_Blower[i] = new Blower(i);
}
Otherwise create an intance of Global and call it's instance method (but that's not what you want I think).
Globals.Global g=new Globals.Global();
g.InstantiateBlowerObj();
Make it static.
You are trying to access a non-static member in an static context.
public static void InstantiateBlowerObj()
{
for (int i = 1; i < 4; i++)
_Blower[i] = new Blower(i);
}

Categories

Resources