I am having two interfaces like ICustomerRepository, IBalanceRepository which are implemented by CustomerRepository.cs and BalanceRepository. Now for entry i have customerservice.cs with constuctor accepting instance of ICustomerRepository. I am calling a method from customerservice.cs to BalanceService.cs which is having constructor accepting instance of IBalancerepository. I registered all classes using unity and resolved customer service, this is resolving ICustomerRespository but not IBalanceRepository. Can we resolve IBalanceRepository repository like this or not? See below code and suggest a solution.
public interface ICusotmerRepository
{
void Add(string strCustomer);
}
public interface IBalanceRepository
{
void Add(decimal decAmount);
}
class CusotmerRepository : ICusotmerRepository
{
public void Add(string strCustomer)
{
Console.WriteLine("Added customer "+strCustomer);
}
}
class BalanceRepository : IBalanceRepository
{
public void Add(decimal decAmount)
{
Console.WriteLine("added amount "+decAmount);
}
}
public class BalanceService
{
private readonly IBalanceRepository _balanceRepository;
public BalanceService(IBalanceRepository balanceRepository)
{
_balanceRepository = balanceRepository;
}
public BalanceService()
{
}
public void AddBalance(decimal decBalance)
{
_balanceRepository.Add(decBalance);
}
}
class CustomerService
{
private readonly ICusotmerRepository _cusotmerRepository;
public CustomerService(ICusotmerRepository cusotmerRepository)
{
_cusotmerRepository = cusotmerRepository;
}
public void Process(string strCustomerName, decimal decBalance)
{
_cusotmerRepository.Add(strCustomerName);
var objBalanceService = new BalanceService();
objBalanceService.AddBalance(decBalance);
}
}
class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
container.RegisterType<IBalanceRepository, BalanceRepository>();
container.RegisterType<ICusotmerRepository, CusotmerRepository>();
var customerService = container.Resolve<CustomerService>();
customerService.Process("Ganesha",7);
}
}
The problem is here:
public void Process(string strCustomerName, decimal decBalance)
{
_cusotmerRepository.Add(strCustomerName);
var objBalanceService = new BalanceService(); <------------
objBalanceService.AddBalance(decBalance);
}
You are calling the parameterless constructor directly - there's nowhere for Unity to "inject" the dependency into BalanceService.
I see three possibilities:
Add a constructor parameter to CustomerService for BalanceService and let Unity inject it
Add a constructor parameter to CustomerService for IBalanceRepository and let Unity inject it, passing it in when you construct BalanceService
Add IBalanceRepository or BalanceService as a parameter to Process
You can't resolve BalanceService in this way because Unity will not be able to know when you need to resolve this dependency.
You can inject BalanceService into customer service through constructor parameter.
Related
I'm trying to use DI to bind a different implementation of my networking class. I've been able to do this successfully using a none generic version of the class. My implementation is as follows:
class MainClass
{
public static void Main(string[] args)
{
IKernel kernel;
// Hardcode here but will be managed by build system.
bool runningInProd = false;
if (runningInProd)
{
kernel = new StandardKernel(new RealNetworkModule());
}
else
{
kernel = new StandardKernel(new FakeNetworkModule());
}
Session session = kernel.Get<Session>();
session.Authenticate();
}
public class RealNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender)).To(typeof(RealRequestSender));
}
}
public class FakeNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender)).To(typeof(FakeRequestSender));
}
}
}
Class that uses my IRequestSender:
public class Session
{
IRequestSender requestSender;
[Inject]
public Session(IRequestSender requestSender)
{
this.requestSender = requestSender;
}
public void Authenticate()
{
Console.WriteLine(requestSender.Send("Hello There"));
}
}
The IRequestSender interface:
public interface IRequestSender
{
string Send(string request);
}
And the two different implementations:
public class RealRequestSender: IRequestSender
{
public string Send(string request)
{
return "RealRequestSender right back at you: " + request;
}
}
public class FakeRequestSender: IRequestSender
{
public string Send(string request)
{
return "FakeRequestSender right back at you: " + request;
}
}
This is very straightforward and it works; however, what I need is for my IRequestSender to use Generic types rather than string for input output:
public interface IRequestSender<RequestT, ResponseT> where RequestT: class where ResponseT: class
{
RequestT Send(RequestT request);
}
And the impl's:
public class FakeRequestSender<RequestT, ResponseT> : IRequestSender<RequestT, ResponseT> where RequestT : class where ResponseT : class
{
public RequestT Send(RequestT request)
{
throw new NotImplementedException();
}
}
public class RealRequestSender<RequestT, ResponseT> : IRequestSender<RequestT, ResponseT> where RequestT : class where ResponseT : class
{
public RequestT Send(RequestT request)
{
throw new NotImplementedException();
}
}
I've come across several examples that address this issue and I've tried to base my implementation on them but I have failed. Here are the two problems that I'm running into:
1) Binding: this is the main problem. Here is what my binding looks like based on solutions I have seen online:
public class RealNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender<>)).To(typeof(RealRequestSender<>));
}
}
VSCode gives me the error:
Program.cs(29,29): Error CS0305: Using the generic type 'IRequestSender<RequestT, ResponseT>' requires 2 type arguments (CS0305) (DI)
Based on this error and what I have read online it is still not clear to me what I need to do here.
2) Accessing IRequestSender: the solution to this might be clear once I know how to fix binding. In the original implementation I used [Inject] to get access to the IRequestSender I need in my Sessions class. However now in the generic version I imagine I will not be able to do this. If I were to use RequestSender without DI it would look like:
RequestSender <AuthRequest, AuthResponse> requestSender = new RequestSender<AuthRequest, AuthResponse>();
or
RequestSender <UserRequest, UserResponse> requestSender = new RequestSender< UserRequest, UserResponse >();
for any number of different types.
So I'm not sure how to go about accessing the RequestSender in this scenario.
Given your current interface, you'll have to specify the generic type arguments when injecting. Assuming your request and response are both strings, your constructor would look like:
public Session(IRequestSender<string, string> requestSender)
{
this.requestSender = requestSender;
}
If you don't want to specify the arguments at creation/injection time, you'll have to change the design a bit. I can't say for certain with the sample code you provided, but it might be possible to remove the generic type args from your interface and place them on the method instead:
public interface IRequestSender
{
RequestT Send<RequestT, ResponseT>(RequestT request)
where RequestT: class
where ResponseT: class;
}
With that definition, you'd inject IRequestSender, and then specify the generic type parameters when calling. For example,
string myResponse = requestSender.Send<string, string>("my string");
Hello first of all I'm just a newbie programmer, I just discovered how dependency injection pattern works and it is used to make my code more loosely coupled. I don't specifically know how to configure a Ninject to resolve the dependency, is it better to use these plug in?
Currently my approach when resolving dependency is like this.
public class MyClass
{
IContract _contract = null;
MyClass()
{
}
MyClass(IContract contract)
{
_contract = contract;
}
public void DoSomething()
{
IContract concreteImplementation = _contract ?? new ConcreteContract();
concreteImplementation.MyMethod();
}
}
public class ConcreteContract : IContract
{
public void MyMethod()
{
//do something;
}
}
public interface IContract
{
void MyMethod();
}
Edward...
I thought I'd add a little detail to my comment. The benefits of DI are as you mention (looser coupling). Also, it allows you to register your contract at both compile and runtime, depending on your requirement. As a result, you can add new implementations without breaking the class that you wish to resolve against.
You'll need a slight refactor to accomplish your goal using Unity. Below is a small self contained example (console app), using your class definitions (and showing an alternative implementation):
public class MyClass
{
readonly IContract _contract = null;
// do not include a paramterless ctor
// thus preventing class being created
// without a concrete implementation of IContract
public MyClass(IContract contract)
{
_contract = contract;
}
public void DoSomething()
{
_contract.MyMethod();
}
}
public class ConcreteContract : IContract
{
public ConcreteContract() { }
public void MyMethod()
{
//do something;
Debug.Print("Hello from the ConcreteContract class");
}
}
public class PlasticContract : IContract
{
public PlasticContract() { }
public void MyMethod()
{
//do something;
Debug.Print("Hello from the PlasticContract class");
}
}
public interface IContract
{
void MyMethod();
}
class Program
{
// add the nuget package Unity 1st
// Install-Package Unity
static void Main(string[] args)
{
// Declare a Unity Container -
// normally done once in the Startup/Bootstrap class
var unityContainer = new UnityContainer();
// Register IContract so when dependecy is detected
// it provides a ConcreteContract instance
// you could change this to <IContract, PlasticContract>
unityContainer.RegisterType<IContract, ConcreteContract>();
// Instance a MyClass class object through Unity
var preferredClass = unityContainer.Resolve<MyClass>();
preferredClass.DoSomething();
}
}
Hope this gets you to the next stage.
I have an interface and class like this
public interface ICustomerEx
{
void Load(DataRow row);
}
public class Customer:ICustomerEx
{
public string Name{get;set;}
public string Address{get;set;}
void Load(DataRow row)
{
Name = (string)row["name"];
Address = (string)row["address"];
}
}
Now I'm building this as a class library and add to another project as a reference.
In that project there's a class called UiCustomer that implements from the same refereced interface ICustomerEx
In this class it has its own property and load that property from its load method.
public class UiCustomer:ICustomerEx
{
public string Telephone{get;set;}
void Load(DataRow row)
{
Telephone=(string)row["tele"];
}
}
Now is there any way to implement my first class's(that build as a class library) Load method to load Ui project's properties after loading it's own properties by using like Dependency Injection.
eg.
public class Customer:ICustomerEx
{
public string Name{get;set;}
public string Address{get;set;}
void Load(DataRow row)
{
Name = (string)row["name"];
Address = (string)row["address"];
//Call load methods in other places that Interface implemented
}
}
It depends what you want. Using separate classes as you have now, you'd need to dependency-inject a list of ICustomerEx objects into each Customer, but then you'd end up with a bunch of different objects each of which would have only a subset of the relevant properties. It sounds like inheritance + the template method pattern might be a better fit:
public class Customer:ICustomerEx
{
public string Name{get;set;}
public string Address{get;set;}
void Load(DataRow row)
{
this.Name = (string)row["name"];
this.Address = (string)row["address"];
this.DoMoreLoading(row);
}
// this method is defined as a no-op in the base class, but it provides an extension point
// for derived classes that want to load additional properties
protected virtual void DoMoreLoading(DataRow row) { }
}
// note that now UiCustomer extends Customer (and thus still implements ICustomerEx
public class UiCustomer : Customer
{
public string Telephone { get; set; }
protected override void DoMoreLoading(DataRow row)
{
this.Telephone = (string)row["tele"];
}
}
// usage
var uiCustomer = new UiCustomer();
uiCustomer.Load(row); // populates name, addr, and telephone
To support instantiating the customer on the library side, you'll need some way to make the library aware of the UiCustomer class.
One way to do this would be to register an ICustomerEx with an IOC container and then resolve the instance using dependency injection:
// in the UI code (this is code for the Autofac IOC container):
ContainerBuilder cb = ...
cb.RegisterType<UiCustomer>().As<ICustomerEx>();
cb.RegisterType<AServiceThatNeedsACustomer>();
// in the library code
public class AServiceThatNeedsACustomer {
private readonly ICustomerEx customer;
// the customer will get injected by the IOC container
public AServiceThatNeedsACustomer(ICustomerEx customer) {
this.customer = customer;
}
}
Alternatively, you could use a factory pattern:
// in the library:
public static class CustomerFactory {
private static volatile Func<ICustomerEx> instance = () => new Customer();
public static Func<ICustomerEx> Instance { get { return instance; } set { instance = value; } }
}
// then to get a customer
var cust = CustomerFactor.Instance();
cust.Load(row);
// in the UI code:
CustomerFactory.Instance = () => new UiCustomer();
You can call the other implementations like this
In the assembly that contains the interface ICustomerEx you can add a registry-class that stores instances of ICustomerEx like this
(Note this is pseudocode to show how it could go.)
public class CustomerRegistry : ICustomerEx {
// singelton
public static final CustomerRegistry theRegistry = new CustomerRegistry();
private ArrayList<ICustomerEx> customers = new ArrayList<ICustomerEx>();
public void RegisterCustomer(ICustomerEx customer) {
customers.add(customer);
}
public void Load(DataRow row)
{
foreach(ICustomerEx customer in customers) {
customer.Load(row);
}
}
}
every implementation of ICustomerEx needs a call to the registry
CustomerRegistry.theRegistry.RegisterCustomer(new UiCustomer());
in your main customer class you use the registry to call the other loads
public class Customer:ICustomerEx
{
void Load(DataRow row)
{
CustomerRegistry.theRegistry.Load(row);
}
}
I have a class, which contain my actions (any logic):
public class socActions
{
public void Choose(int elem)
{
switch(elem) ... CalcA(elem) || CalcB(elem) ...
}
public void CalcA()
{
}
public void CalcB()
{
}
public void CalcC()
{
}
}
So, in my program, when i get elem value, i use it like:
(new socActions()).Choose(elem_val);
Okey, but in socActions class methods, i'd like to have a connection with my repository or make any other dependency injection.
If i add IRepositoryMy repositoryMy to constructor, then i couldn't
create classes as above, bcz its need now constructor with argument
IRepositoryMy.
If i try to make injection in field, it doesn't work
(property = null).
If i try to make injection in methods (CalcA,
CalcB) it doesn't work too.
How i really should make this task (inject class, for example repository)? Don't want to mark everything in my application as static :(
WinForms, C#, Ninject 3
Edit:
public class socActions
{
[Inject]
public IGridProcessor _GridProcessor { private get; set; }
so, in method its null:
public void UpdateInfo(...)
{
...
this._GridProcessor.Refresh();
}
In other classes, where i inject IGridProcessor to class in constructor, everything fine.
In Program.cs:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var kernel = new StandardKernel(new TwttModule());
var form = kernel.Get<Main>();
Application.Run(form);
}
public class TwttModule : NinjectModule
{
public override void Load()
{
Bind<IGridProcessor>().To<GridProcessor>();
}
}
public static class AnyClass
{
public static void Act()
{
....
(new socActions()).Choose(elem_val);
}
}
How should i inject IGridProcessor to socActions?
When using constructor injection, you don't construct your classes directly, but rather ask ninject for an instance. Based on how you've configured ninject, you get a new instance, or a singleton instance, etc.
From their docs:
Samurai warrior = kernel.Get<Samurai>();
Suppose I have IRepository interface and its implementation SqlRepository that takes as an argument LINQ to SQL DataContext. Suppose as well that I have IService interface and its implementation Services that takes three IRepository, IRepository and IRepository. Demo code is below:
public interface IRepository<T> { }
public class SqlRepository<T> : IRepository<T>
{
public SqlRepository(DataContext dc) { ... }
}
public interface IService<T> { }
public class Service<T,T1,T2,T3> : IService<T>
{
public Service(IRepository<T1> r1, IRepository<T2>, IRepository<T3>) { ... }
}
Is it any way while creating Service class to inject all three repositories with the same DataContext?
All you need to do is make sure when you register the Datacontext with your Unity container use the PerResolveLifetimeManager either in config:
<type type="<namespace>.DataContext, <assembly>">
<lifetime type="Microsoft.Practices.Unity.PerResolveLifetimeManager, Microsoft.Practices.Unity" />
</type>
or in code:
container.RegisterType<DataContext>(new PerResolveLifetimeManager());
then whenever the container resolves the Service any dependencies which also require a DataContext will be provided with exactly the same one. But the next request to resolve Service will create a new DataContext.
I think I know what you want to do. I'm in the same boat and am trying to come up with a solution.
My Service layer performs operations on in coming requests, and what it does depends on the contents. It passes it to a series of chain of responsibility classes. I want the same context passed to all classes within the lifetime of the service method called
You can Specify PerResolveLifetimeManager. So far, it seems to be working with my test cases:
Service Class:
public interface IServiceClass
{
void DoService();
}
class ServiceClass : IServiceClass
{
private IHandler Handler { get; set; }
public ServiceClass(IHandler handler)
{
Handler = handler;
}
public void DoService()
{
Handler.HandleRequest();
}
}
IHandler is implemented by two classes, and performs Chain of Responsibility pattern:
public interface IHandler
{
void HandleRequest();
}
class Handler : IHandler
{
private IDataContext DataContext { get; set; }
public Handler(IDataContext dataContext)
{
DataContext = dataContext;
}
public void HandleRequest()
{
DataContext.Save("From Handler 1");
}
}
class Handler2 : IHandler
{
private IDataContext DataContext { get; set; }
private IHandler NextHandler { get; set; }
public Handler2(IDataContext dataContext, IHandler handler)
{
DataContext = dataContext;
NextHandler = handler;
}
public void HandleRequest()
{
if (NextHandler != null)
NextHandler.HandleRequest();
DataContext.Save("From Handler 2");
}
}
As you can see, both handlers accept an instance of IDataContext, which I want to be the same in both of them. Handler2 also accepts an instance of IHandler to pass control to (it does both here to demonstrate, but actually, only one would handle the request...)
IDataContext. In the constructor I initialize a Guid, and during its operation, output it so I can see if both times its called is using the same instance:
public interface IDataContext
{
void Save(string fromHandler);
}
class DataContext : IDataContext
{
private readonly Guid _guid;
public DataContext()
{
_guid = Guid.NewGuid();
}
public void Save(string fromHandler)
{
Console.Out.WriteLine("GUI: [{0}] {1}", _guid, fromHandler);
}
}
Finally, registration and calling of service:
private IUnityContainer container;
private void InitializeUnity()
{
container = new UnityContainer();
container.RegisterType<IHandler, Handler2>("Handler2",
new InjectionConstructor(new ResolvedParameter<IDataContext>(), new ResolvedParameter<IHandler>("Handler1")));
container.RegisterType<IHandler, Handler>("Handler1");
container.RegisterType<IDataContext, DataContext>(new PerResolveLifetimeManager());
container.RegisterType<IServiceClass, ServiceClass>("MyClass", new InjectionConstructor(new ResolvedParameter<IHandler>("Handler2")));
}
private void CallService()
{
var service = container.Resolve<ServiceClass>("MyClass");
service.DoService();
// Resolving and calling again to simulate multiple resolves:
service = container.Resolve<ServiceClass>("MyClass");
service.DoService();
}
This is the output I get:
GUI: [f2250055-8a5f-4f80-a1b6-bcc5574138cf] From Handler 1
GUI: [f2250055-8a5f-4f80-a1b6-bcc5574138cf] From Handler 2
GUI: [22a5c0a3-3c5c-4683-807d-bf2b43f3cd0a] From Handler 1
GUI: [22a5c0a3-3c5c-4683-807d-bf2b43f3cd0a] From Handler 2
Hope this wall of text answered your question... If not sorry, it did inspire a solution I needed to implement...
If I understand your question correctly (and if you are using unity...I suppose you do because you have taggged it with unity) you could do something like this:
In your repository implementions,
[InjectionConstructor]
public SqlRepository(
[Dependency] DataContext ctx)
but then you have to mark the service contructor in the same manner and use the container to resolve your services as well as the repository. The DataContext also has to be in the container to make it work.
An alternative approach is to do something like this with your repository:
[InjectionMethod]
public void Initialize(
[Dependency] DataContext ctx
this will tell unity to call this method if you will, in your service constructor, use unity with the BuildUp method...something like this:
unitycontainer.BuildUp<IRepository>(repository);
I guess that´s not quite what your looking for but please tell me if I´m on the right track and I´ll see if I can help you further...
Cheers / J
Have you tried using the RegisterInstance() method for the unity container? Something like this might work:
public static UnityContainer CreateContainer()
{
UnityContainer container = new UnityContainer();
try
{
var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
if (section != null)
{
section.Containers[0].Configure(container);
}
}
catch (Exception ex)
{
TraceLogger.LogMessage("Configurarion Error for Unity Container", ex.Message, TraceEventType.Critical);
Environment.Exit(1);
}
container.RegisterInstance(new DataContext());
return container;
}
Now, every time this container tries to build an object which needs a DataContext, the same instance will be passed. You could even configure the DataContext before registering its instance.
UPDATE:
One option (now, I don't know if its really a good practice, but this worked for me) is to create a different container for each object you're gonna create. Something like:
UnityContainer container1 = ContainerFactory.CreateContainer();
UnityContainer container2 = ContainerFactory.CreateContainer();
UnityContainer container3 = ContainerFactory.CreateContainer();
MyObject1 object1 = container1.Resolve<MyObject1>();
MyObject2 object2 = container2.Resolve<MyObject2>();
MyObject3 object3 = container3.Resolve<MyObject3>();
or a more summarized way:
MyObject1 object1 = ContainerFactory.CreateContainer().Resolve<MyObject1>();
MyObject1 object2 = ContainerFactory.CreateContainer().Resolve<MyObject2>();
MyObject1 object3 = ContainerFactory.CreateContainer().Resolve<MyObject3>();
Well, there's a lot of ways to do it, creating a list, using the factory pattern. Hope it helps