How to inject dependencies with XmlSerializer and Autofac? - c#

I have a class named SomeRule that can be serialized in a XML format. The class uses an ISomeService that I would like to be injected via autofac.
[Serializable]
public class SomeRule
{
[XmlAttribute("Attribute1")]
public string Attribute1 {get;set;}
[XmlAttribute("Attribute2")]
public string Attribute2 { get; set; }
private readonly ISomeService m_someService;
private SomeRule() { }
public SomeRule(ISomeService someService)
{
m_someService = someService;
}
public void DoSomething()
{
m_someService.DoStuff(Attribute1);
}
}
public interface ISomeService {
void DoStuff(string param);
}
public class SomeServiceImpl : ISomeService
{
public void DoStuff(string param) => // Do something with the stuff.
}
Now, my program receives an XML string that I would like to deserialize but also, at the same time, have autofac inject the dependency for me.
void Main()
{
string serializedRule =
"<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
"<SomeRule xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"Attribute1=\"Huuuuuge\" " +
"Attribute2=\"Cofveve\" />";
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SomeRule));
var stringBuilder = new StringBuilder(serializedRule);
var newRule = xmlSerializer.Deserialize(
new StringReader(stringBuilder.ToString())) as SomeRule;
// ISomeService was not injected yet. Is it possible?
}
I can make this work by calling the autofac container, get the registered implementation of the ISomeService interface and assign it to a public property of the SomeRule instance. I am looking for a better solution, one that would not require the class to have a public property.
Is there a way to automatically inject dependencies with XmlSerializer?

From a DI standpoint, having data-centric objects with constructors that accepts service dependencies is rather problematic, and should be prevented.
When practicing DI, we try to centralize the composition of our object graphs of application components (i.e. the classes that contain behavior and have dependencies of their own) to a centralized place in the application called the Composition Root.
A data-centric object that includes constructor dependencies, however, complicates this practice, since it either forces composition out of the Composition Root, or forces the addition of factory abstractions for the creation of these objects.
Instead, you should use one of following two alternatives:
Separate data and behavior. This means moving SomeRule's DoSomething method to a new class, that takes SomeRule as an argument in its public method(s). The constructor dependency will move to this new class as well.
Remove the constructor dependency of SomeRule and instead inject it into DoSomething using method injection.
Option 1 might look like this:
// SomeRule only contains data. Much simpler
[Serializable]
public class SomeRule
{
[XmlAttribute("Attribute1")]
public string Attribute1 {get;set;}
[XmlAttribute("Attribute2")]
public string Attribute2 { get; set; }
}
// Moved behavior to new class. This class can be injected
// into consumers, as usual.
public class SomeRuleHandler : IRuleHandler<SomeRule>
{
private readonly ISomeService m_service;
// There's now just one constructor left
public SomeRuleHandler(ISomeService service)
{
m_service = service ?? throw new ArgumentNullException("service");
}
public void DoSomething(SomeRule rule)
{
m_service.DoStuff(rule.Attribute1);
}
}
With option 2, the result will be the following:
[Serializable]
public class SomeRule
{
[XmlAttribute("Attribute1")]
public string Attribute1 { get; set; }
[XmlAttribute("Attribute2")]
public string Attribute2 { get; set; }
// No more constructors. The dependency is supplied in the method,
// but *not* stored.
public void DoSomething(ISomeService service)
{
service.DoStuff(Attribute1);
}
}

Related

Is There a Way to Inject A Dependency to a Helper Class Using IoC Container?

I have a helper class that I'm instantiating in one of my services. I was wondering if there is a way to inject the Repository using the IoC container and have it as a property instead of passing the auto-wired repository from the service.
This is because this helper class is implementing an interface and other classes that does implement this might not necessarily need to take that in that specific method.
I'm trying to solve this without changing a lot of code.
public class SomeService : Service
{
public IRepository Repo { get; set; }
public object Get(Request req)
{
var helper = new SomeServiceHelper();
var somethingFromHelper = helper.GetSomething();
var SomethingFromRepo = Repo.GetSomethingElse();
.
.
.
}
public object Post(Request req)
{
Repo.SaveSomething(something);
}
}
public class SomeServiceHelper : IHelper
{
public IRepository Repo { get; set; }
public object GetSomething()
{
Repo.GetSomethingFromDB();
.
.
.
}
}
This is because this helper class is implementing an interface and other classes
that does implement this might not necessarily need to take that in that specific method.
You don't need to register your helper class against an interface, you can just register the concrete type, e.g:
container.RegisterAutoWired<SomeServiceHelper>();
Or:
container.Register(c => new SomeServiceHelper {
Repo = c.Resolve<IRepository>(),
});
Then you could have either or both injected in your Service:
public class SomeService : Service
{
public SomeServiceHelper Helper { get; set; }
public IRepository Repo { get; set; }
}

What is the right implementation of the Dependency Inversion Principle in C#?

I'm building a password generator. I'm trying to apply the Dependency Inversion Principle (DIP) but so far my solution still seems to be coupled with concrete data.
How do I decouple the PasswordGenerator? So I don't have to pass to it
new PasswordRequirementsRepository(new PasswordRequirements{[properties assigned here]})
and I can inject an interface instead which will be used by IoC Container?
How can I pass in the data assigned to PasswordRequirements properties to the PasswordGenerator without creating an instance of PasswordRequirementsRepository?
I'm struggling when passing different sets of password requirements because in PasswordGenerator I have to pass a concrete instance of PasswordRequirementsRepository instead of interface. I guess what I'm trying to achieve is to decouple PasswordGenerator from the concrete set of password requirements.
IPasswordRequirementsRepository.cs
public interface IPasswordRequirementsRepository
{
PasswordRequirements GetPasswordRequirements();
}
PasswordRequirementsRepository.cs
public class PasswordRequirementsRepository : IPasswordRequirementsRepository
{
private readonly PasswordRequirements _requirements;
public PasswordRequirementsRepository(PasswordRequirements requirements)
{
_requirements = requirements;
}
public PasswordRequirements GetPasswordRequirements()
{
return _requirements;
}
}
IPasswordGenerator.cs
public interface IPasswordGenerator
{
string GeneratePassword();
}
PasswordGenerator.cs
public class PasswordGenerator : IPasswordGenerator
{
private readonly IPasswordRequirementsRepository _repository;
public PasswordGenerator(IPasswordRequirementsRepository repository)
{
_repository = repository;
}
public string GeneratePassword()
{
PasswordRequirements requirements = _repository.GetPasswordRequirements();
[password generation logic here]
}
}
PasswordRequirements.cs
public class PasswordRequirements
{
public int MaxLength { get; set; }
public int NoUpper { get; set; }
public int NoLower { get; set; }
public int NoNumeric { get; set; }
public int NoSpecial { get; set; }
}
How do I decouple the PasswordGenerator? So I don't have to pass to it and I can inject an interface instead which will be used by IoC Container?
1st - Derive an interface:
public class IPasswordRequirements
{
int MaxLength { get; }
int NoUpper { get; }
int NoLower { get; }
int NoNumeric { get; }
int NoSpecial { get; }
}
2nd - Inherit from interface:
public class PasswordRequirements : IPasswordRequirements
{
public int MaxLength { get; set; }
public int NoUpper { get; set; }
public int NoLower { get; set; }
public int NoNumeric { get; set; }
public int NoSpecial { get; set; }
}
3rd - Update constructor:
public class PasswordGenerator : IPasswordGenerator
{
public PasswordGenerator(IPasswordRequirements passwordRequirements)
{
}
That's it.
Don't use a repository here
My fear is that your understanding of a repository and DI infer some time of requirement to always be used together. What I believe your lacking is the code that instantiates dependencies. While a repository may at it's core provide that as a bases of it's pattern, it isn't the correct choice here, because of two reasons; first you aren't storing the items in the repository (that is there is no tier virtual or physical abstraction to wrap the repository around) and secondly you aren't providing generic access to a wide variety of types, just a single one.
At it's core the only thing a repository needs to be useful is a configuration/object to pass objects.. to some other tier (SQL, File system, Web API). A repository is not required in all instances to know anything about how objects are created.
Choose a framework that fits your need
Instead, what you need is a framework built at it's core around DI; object creation and disposal, and having an interface/configuration in which to configure the framework so it can be aware of dependencies to assist in the creation of dependent objects. There are three that come to mind AutoFac, Ninject and Unity. In each of these case, you are in some way, required to configure each type and use it's pattern to create objects. In many cases these Frameworks can even be full featured replacements with other Microsoft Frameworks (MVC for example, has it's own way to instantiate objects, but can be replace with other DI Frameworks). In no way are these frameworks required to know configuration on how to pass these objects to other tiers. It may do so simply by configuration as a by-product, but at it's core that's not what is configured.
For example with Autofac, first you create builder which is basically a fancy way to create a configuration:
var builder = new ContainerBuilder()
Then you register your types:
builder.RegisterType<PasswordRequirements>.As<IPasswordRequirements>();
Create a Container which manages objects: from their instantiation to their configuration.
var container = builder.Build();
Create a scope which defines the duration of an objects lifetime.
using (var scope = new BeginLifetimeScope())
{
// all objects created by scope which be disposed when the scope is diposed.
var passwordRequirements = scope.Resolve<IPasswordRequirements>();
}
By default passwordRequirements will be a new PasswordRequirements(). From there you simply build out your necessary dependency requirements and let the framework handle the rest.
Crux of the issue related to Dependency Inversion
On creating the instance of the PasswordGenerator. which inject, IPasswordRequirementsRepository, in current design there's a limitation of passing the concrete instance of PasswordRequirements, which shall be avoided for true Dependency inversion design.
Following are the possible solutions:
Create an interface or preferably an abstract class for the PasswordRequirements, which can be overridden and can be injected on the need basis, which will be automatically injected when IPasswordRequirementsRepository is injected in the PasswordGenerator
Let's consider the abstract class:
public abstract class BasePasswordRequirements
{
public abstract int MaxLength { get; set; }
public abstract int NoUpper { get; set; }
public abstract int NoLower { get; set; }
public abstract int NoNumeric { get; set; }
public abstract int NoSpecial { get; set; }
}
public class PasswordRequirements : BasePasswordRequirements
{
public override int MaxLength { get; set; }
public override int NoUpper { get; set; }
public override int NoLower { get; set; }
public override int NoNumeric { get; set; }
public override int NoSpecial { get; set; }
}
Using Ninject DI container Binding would be as follows, along with named binding:
Kernel.Bind<IPasswordRequirementsRepository>().To<PasswordRequirementsRepository>()
Kernel.Bind<BasePasswordRequirements>().To<PasswordRequirements>()
PasswordRequirementsRepository will be as follows:
public class PasswordRequirementsRepository : IPasswordRequirementsRepository
{
private readonly BasePasswordRequirements Requirements{get;}
public PasswordRequirementsRepository(BasePasswordRequirements requirements)
{
Requirements = requirements;
}
public BasePasswordRequirements GetPasswordRequirements()
{
return Requirements;
}
}
Another option would be constructor Injection, in that case PasswordRequirements, may not need a Base class or interface, in that case binding would be like:
Kernel.Bind<IPasswordRequirementsRepository>().To<PasswordRequirementsRepository>()
.WithConstructorArgument("requirements", new
PasswordRequirements { .... });
This would call the correct constructor, with relevant values filled in
You may also consider combination of both approached 1 and 2 , where you create a base class / interface for PasswordRequirements and also constructor injection.
For various versions of PasswordRequirements, that you may want to inject consider named binding, following shall be example, instead of:
public class PasswordRequirementsRepository : IPasswordRequirementsRepository
{
private readonly Func<string,BasePasswordRequirements> RequirementsFunc{get;}
public PasswordRequirementsRepository(Func<string,BasePasswordRequirements> requirementsFunc)
{
RequirementsFunc = requirementsFunc;
}
public BasePasswordRequirements GetPasswordRequirements(string name="Version1")
{
return requirementsFunc(name);
}
}
Ninject Binding would be as follows
Kernel.Bind<Func<string,BasePasswordRequirements>>()
.ToMethod(context => name => context.Kernel
.Get<BasePasswordRequirements>(name);
);
Bind<BasePasswordRequirements>().To<PasswordRequirements>().Named("Version1");
Bind<BasePasswordRequirements>().To<AnotherPasswordRequirements>().Named("Version2");
Here the Name for Binding can be passed at the run-time to tweak object that will be injected and thus change the behavior by run-time, thus achieving dependency inversion by using a DI framework like Ninject, which lot of flexible options
Based on the code snippet in your question, the implementation of PasswordGenerator is decoupled from the implementation of the IPasswordRequirementsRepository as it is the interface that is given as constructor argument and not a specific implementation.
To decouple the PasswordRequirementsRepository from a specific implementation of the PasswordRequirements you can do one of two things.
Introduce an interface IPasswordRequirements.
Make PasswordRequirements abstract.
Either approach will decouple the implementation of PasswordRequirementsRepository from the implementation of PasswordRequirements.
DI container
How do I decouple the PasswordGenerator? So I don't have to pass to it
new PasswordRequirementsRepository(new PasswordRequirements{[properties assigned here]})
and I can inject an interface instead which will be used by IoC Container? How can I pass in the data assigned to PasswordRequirements properties to the PasswordGenerator without creating an instance of PasswordRequirementsRepository?
I believe that this part of the question builds on a misunderstanding of the role of the DI container. When building your container you will register all the Classes/Interfaces that is needed in your system. This could look something like the following:
Register<IPasswordRequirements>().To<PasswordRequirements>();
Register<IPasswordRequirementsRepository>().To<PasswordRequirementsRepository>();
Register<IPasswordGenerator>().To<PasswordGenerator>();
After registering everything you can ask the container to provide you with an instance of an interface. In your case, this would be an instance of IPasswordGenerator. The request typically looks a something like this:
var passwordGenerator = contain.Resolve<IPasswordGenerator>();
Normally you only request the topmost component of your program, as the DI container knows what is needed to instantiate every class the component depends on. You would not create a new instance of PasswordGenerator by manually resolving the dependencies and the inject these into the constructor. This approach counteracts the purpose of the DI container.
One option might be to use generics to abstract out the different types of password requirements you might use, and pass the options through the GeneratePassword method since that's really a parameter to how you generate the password. I.E.
interface IPasswordGenerator<TPasswordRequirements>
{
string GeneratePassword(TPasswordRequirements reqs);
}
interface IPasswordRequirementRepository<TPasswordRequirements>
{
TPasswordRequirements GetPasswordRequirements();
}
Implemented by
class DefaultPasswordReqs
{
public int MaxLength { get; set; }
// ...
}
class DefaultPasswordGenerator : IPasswordGenerator<DefaultPasswordReqs>
{
public string GeneratePassword(DefaultPasswordReqs reqs)
{
// ... logic specific to DefaultPasswordReqs
}
}
class InMemoryPasswordRequiremntsRepository<TPasswordRequirements> :
IPasswordRequirementRepository<TPasswordRequirements>
{
private readonly TPasswordRequirements _reqs;
public InMemoryPasswordRequiremntsRepository(TPasswordRequirements reqs)
{
_reqs = reqs;
}
public TPasswordRequirements GetPasswordRequirements()
{
return _reqs;
}
}
And then in whatever code depends on the password generator, have it take a dependency which has the specifc type of password requirements it will use and read the requirements and use those requirements to generate the password.
var requirements = _passwordRequiremntsRepository.GetPasswordRequirements();
var password = _passwordGenerator.GeneratePassword(requirements);

Instantiating a new object with Constructor parameters using Ninject

I'm trying to refactor some code to use IoC with the Ninject framework. So far I have managed to successfully inject in classes in scenarios where I do not have any constructor parameters to pass. However I am having difficulties when it comes to passing in parameters. This is the third binding in the binding class below.
Binding Class
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<Logger>();
Bind<IPlayerDatadao>().To<PlayerDatadao>();
Bind<IPlayerScores>().To<PlayerScores>();
}
}
The logger class has a parameterless constructor and works fine when transferred to Ninject.
Success
// IoC creation
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
//Log User details
var logger = kernel.Get<ILogger>();
logger.LogVisitorDetails();
However, my attempt below threw an exception
Failure
string priceString = Foo();
string pointsString = Bar();
return kernel.Get<IPlayerScores>(new[] { new ConstructorArgument("pointsString", pointsString), new ConstructorArgument("points", priceString) });
This is the class with its constructor.
Class to Inject
public class PlayerScores : IPlayerScores
{
[Inject]
public string points { get; set; }
[Inject]
public string price { get; set; }
public PlayerScores(string Points, string Price)
{
points = Points;
price = Price;
}
}
I'm really not sure how I should be handling the parameters either in the binding class or at the point of injection
I'm really not sure how I should be handling the parameters either in the binding class or at the point of injection
At binding. You should remove any Ninject dependencies from your model:
public class PlayerScores : IPlayerScores
{
public PlayerScores(string points, string price)
{
this.Points = points;
this.Price = price;
}
public string Points { get; set; }
public string Price { get; set; }
}
and then configure the kernel:
Bind<IPlayerScores>()
.To<PlayerScores>()
.WithConstructorArgument("points", "some points")
.WithConstructorArgument("price", "some price");
or using ToMethod which is a bit more refactor friendly as it avoids the magic strings with the parameter names:
Bind<IPlayerScores>()
.ToMethod(ctx => new PlayerScores("some points", "some price"));
This being said, if the 2 parameters are so volatile that they need to have a different value on each call, then you probably should not be passing them as constructor parameters but rather as parameters to some instance method that you would invoke on the class at runtime.

Windsor Castle object factory "GetByName" injecting properties

I use Castle Windsor in my c# project for DI and I've this scenario:
public class Class1:IMyClass
{
public string Name{get{return "Class1";}}
public int Version {get; set;}
private string _description;
public Class1(string description)
{
this._description=description;
}
}
public class Class2:IMyClass
{
public string Name{get{return "Class2";}}
public int Version {get; set;}
private string _description;
public Class2(string description)
{
this._description=description;
}
}
I can register those classes by the common IMyClass interface but now I need a factory for create a determinated instance; something like this:
IMyClass _myClass= someClassFactory.GetByName("Class2", version=1, description="test");
Is there an example for a factory that resolves a component by name and inject properties and/or constructor values?
Absolutely right Cristiano. Here a bit more info.
No matter how you write your factory you will not be able to create component based on the Name property. The reason for this is that the property is only availble after creating the object, and the factory needs it before that.
Create a factory :
interface ISomeClassFactory
{
IMyClass GetById(string name, int version, string description);
}
and a selector (copied from: http://docs.castleproject.org/Windsor.Typed-Factory-Facility-interface-based-factories.ashx)
public class CustomTypedFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
if(method.Name == "GetById" && arguments.Length == 1 && arguments[0] is string)
{
return (string)arguments[0];
}
return base.GetComponentName(method, arguments);
}
}
And register these as follows:
Component.For<IMyClass>().ImplementedBy<Class1>().Named("Class1"),
Component.For<IMyClass>().ImplementedBy<Class2>().Named("Class2")
Component.For<IISomeClassFactory>().AsFactory(c=> new CustomTypedFactoryComponentSelector())
Also make sure to add the TypedFactoryFacility to the container.
Once again Typed factory is the solution.

Data Containers vs Objects coupled with behaviour

I am writing a storage solution for a workflow hierarchy.
To simplify the picture I have 2 types of objects, a Workflow and a WorkflowStep.
Even though WorkflowStep comes hierarchically under the Workflow, the Workflow does not aggregate WorkflowStep because we view these objects as just data containers.
So this leaves me with the following classes:
public class Workflow : Node {
public string UID;
public string parentID;
}
public class WorkflowStep : Node {
public string UID;
public string parentID;
}
public class WorkflowEngine {
public void Store(Workflow wf) {
}
public void Store(WorkflowStep wfs) {
}
}
The reasoning for not aggregating WorkflowStep inside Workflow (even though logically that fits) is that these objects are purely viewed as data containers and they may be subject to changes later on and we want to keep the storage of these objects decoupled from the objects themselves.
The other alternative of course would be to do something like this:
public class Workflow : Node {
public List<WorkflowStep> steps;
public string UID;
public string parentUID;
public void Store() { }
}
public class WorkflowStep : Node {
public string UID;
public string parentID;
public void Store() { }
}
What are the pros and cons of either approach? Is there any literature that talks about both the designs?
Even though Workflow and WorkflowStep are both data containers but keeping these aside from hierarchical measures doesn't solve your decoupling issue.
It is more logical to keep WorkflowStep on hierarchy of Workflow and to get along with decoupling you must introduce IoC in this case.
The Beauty of IoC is that changing the definitions of WorkflowStep which is a list in Workflow class will be just transparent where you will only be considering to register your types on your IoC container.
Let me put you on an example with Ninject IoC container framework.
Define interfaces and implement your data containers accordingly:
public interface IWorkflow {
string UID { get; set; }
string parentID { get; set; }
IList<IWorkflowStep> Steps { get; set; }
}
public interface IWorkflowStep {
string UID { get; set; }
string parentID { get; set; }
}
public class Workflow : IWorkflow, Node {
public string UID { get; set; };
public string parentID { get; set; };
public IList<IWorkflowStep> Steps { get; set; }
}
public class WorkflowStep : IWorkflowStep, Node {
public string UID { get; set; };
public string parentID { get; set; };
}
And now, the Ninject module be:
public class WorkflowModule : NinjectModule
{
#region Overrides of NinjectModule
public override void Load()
{
Bind<IWorkflow>().To<Workflow>();
Bind<IWorkflowStep>().To<WorkflowStep>();
Bind<IList>().To<List>();
}
#endregion
}
This is the single place where you bind your interfaces with concrete classes. And rest of the world, you just ask for an instance of defined interface.
To resolve your type, you need to create a Ninject Kernel which is an IKernel type and a concrete implementation of StandardKernel by loading your defined module.
Which is something like,
var kernel = new StandardKernel(new WorkflowModule());
Now, all you have to do is resolve your desired interface, like:
IWorkflow workflow = kernel.Get<IWorkflow>();
IWorkflowStep workflowStep = kernel.Get<IWorkflowStep>();
The beauty here is, you don't need to worry about your concrete implementation and which is very tightly coupled within your system. Its just the interface you will be dealing with and rest are the worries of your IoC container implementation.
As you are more worried about the implementation of WorkflowStep to be changed and not coupling with Workflow. I guess, this is where IoC comes to play.
Please be noted that, you can use any IoC container framework like Unity, Spring.NET, StructureMap and etc. I used Ninject because I am comfortable with it.

Categories