IoC, Mixing injections with parameters in the constructor? - inversion-of-control

I am new to Inversion of Control (IoC), so I wanted to know the best strategy to handle
the case where I want to pass data structures/parameters as well as injected
objects into a class.
A simple example:
public class EmailSender
{
public EmailSender(string toEmail, string Subject, String body,
ILogger emailLogger)
{.....}
}
What is the best strategy here? I guess it's not possible to inject directly?
I guess I need to put all the string parameters as setters instead and
just have the Ilogger in the constructor, or the other way around?
Or am I wrong?
P.s. I know the example above sucks and toEmail and body should be passed in a separate method call, but it was just to make an example.

No, you should be able to specify the strings in the constructor call. Admittedly I'd usually expect those to be more "transient" values passed in as method arguments:
public class EmailSender
{
private readonly ILogger emailLogger;
public EmailSender(ILogger emailLogger)
{
this.emailLogger = emailLogger;
}
public void SendEmail(string toEmail, string subject, string body)
{
// ...
}
}
That way the same EmailSender can be used to send many emails - the details of the email itself "flow through" the sender rather than being part of it.
EDIT: Given the edit to the question, it's not entirely clear what remains. If you're really asking how to specify strings as constructor arguments, that will depend on the IoC framework you're using. If you could specify the framework, we could probably give you the appropriate syntax.

Related

CQRS - Command/Query single parameter

All the examples showcasing the CQRS pattern always have 0 or 1 parameter.
For example:
public class MyCommand
{
public int Value { get; set; }
}
public class MyCommandHandler
{
public void Handle(MyCommand myCommand)
{ ... }
}
Assuming we are calling the handle directly is there is any reason besides the implementation details?
I'm aware of the advantages of having a single parameter, like encapsulating all the required data to perform the action and also making it easier to serialize if we have to work with Queues of Q/C, validation, etc..
But is it "wrong" to have multiple parameters in the handler?
But is it "wrong" to have multiple parameters in the handler?
No; it's tradeoffs.
When we have handlers with incompatible signatures, then composing handlers -- for instance, creating a handler with some cross cutting concerns -- takes more work because of the number of variations required.
No, it is not, I would say that it is sometimes advisable to use multiple parameters to separate concerns. Because you might have traceID, correlationID, or other types of technical data that you don't want to combine with business data. When you send a request, you are using headers, so when sending a message for handling, headers can be used as well
public class MyCommandHandler
{
public void Handle(MyCommand myCommand, MyHeader $header, MySecondHeader $secondHeader)
}
Also, if you don't want to inject dependencies in constructor for whatever reason, it is ok to inject them as parameters.

Jersey Jaxb Issues

We are having a problem with generic Payload while using Jersey. Here is our Domain object.
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Event<T> {
private T eventPayload;
private String eventType;
}
Here we have top level domain object defined. But the internal domain object is generic.
Now on the resource endpoint we have something like this as we know that the sub-domain object we were expecting is.
#POST
#Path("log")
#Consumes(MediaType.APPLICATION_XML)
public Response writeLog(Event<LogPayload> event)
But this doesn’t work.
The event instance is created but the subdomain is not populated correctly.
It just tries to populate the sub-domain object with any random domain object which has the same root element as in the XML (there may be more than one).
Our Solution:
This is our solution, but I am sure this is not the best.
We have to modify our parent domain object have a String variable which stores XML-representation of the generic payload in a String format. For this we have had to write our own Jaxb marshaller.
Modifications to the Event
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Event<T> {
#XmlTransient
private T eventPayload;
private String eventType;
private String payLoadXML;
// Changes to the constructor:
public Event(T eventPayload ……) {
super();
this.eventPayload = eventPayload;
payLoadXML = JAXBUtils.marshall(eventPayload,false); }}
On the resource side once we get the parent Event object, we have to again use our own jaxb marshaller to get the required domain object from the payloadXML as follows.
#POST
#Path("log")
#Consumes(MediaType.APPLICATION_XML)
public Response writeLog(Event<LogPayload> event)
LogPayload log1 = (LogPayload) JAXBUtils.unMarshall(
event.getPayLoadXML(),LogPayload.class);
So ineffect we are using our jaxbmarshaller to marshall and unmarshall the generic subdomain object before and after making the rest call….
Please lets us know if there is a better way to do this ?
Thanks,
ND
I've seen the same question before and I don't think this will work as you originally planned. Web services (json/xml, rest/soap) usually create a service description (like wsdl) and a generic type technically cannot be part of this description. What you could do is to publish multiple services where Event is not generic anymore.

Is there a difference between SimpleIoc.Default.GetInstance and ServiceLocator.Current.GetInstance

I am using version 4 of MVVM Light for Windows 8; it includes SimpleIOC. In various examples I sometimes see code to request an object based on SimpleIoc... and sometimes it is based on ServiceLocator...
Examples include:
userToken = SimpleIoc.Default.GetInstance();
mainVM = ServiceLocator.Current.GetInstance();
What is the difference between using SimpleIoc.Default.GetInstance and ServiceLocator.Current.GetInstance?
If there is no difference, does ServiceLocator just let me to have an option to change my mind about what IOC library I want to use? Does ServiceLocator just provide an additional layer of abstraction that is irrelevant if I am satified with SimpleIoc; or, does ServiceLocator perform some other useful magic that is not obvious to we IOC novices?
Thanks for the insight!
In your ViewModelLocator class you probably have the following line of code:
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc implements the IServiceLocator interface, which means that the ServiceLocator will use it as a DI source when invoked.
Edit:
OK, people want the "full fat and don't spare the cream" answer. Here we go!
ServiceLocator is basically a shell. The code for Service locator is:
public static class ServiceLocator
{
private static ServiceLocatorProvider currentProvider;
public static IServiceLocator Current
{
get
{
return ServiceLocator.currentProvider();
}
}
public static void SetLocatorProvider(ServiceLocatorProvider newProvider)
{
ServiceLocator.currentProvider = newProvider;
}
}
Yup, that's it.
What's ServiceLocatorProvider? It's a delegate that returns an object that implements IServiceLocator.
SimpleIoc Implements IServiceLocator. So when we do:
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
We put our SimpleIoc object into the ServiceLocator. You can use either of these now because whether you call ServiceLocator.Current or SimpleIoc.Default you're returning the same object instance.
So, is there any difference between
userToken = SimpleIoc.Default.GetInstance();
mainVM = ServiceLocator.Current.GetInstance();
?
Nope. None. Both are singletons exposing a static property that is an implementation of IServiceLocator. As mentioned above, you're returning the same instance of object that implements IServiceLocator regardless of which you call.
The only reason why you might want to user ServiceLocator.Current.GetInstance() rather than SimpleIoc.Default.GetInstance() is that at some point in the future you may change DI containers and, if you use ServiceLocator, you won't have to change your code.
Based on Mr. Bugnion's article on MSDN (in the section, "Various Ways to Register a Class"), I am presuming interchangeability of IoC providers is the one and only reason for using ServiceLocator.
As #FasterSolutions stated, SimpleIoc implements IServiceLocator, so I suspect the opposite to your statement about abstraction layers is true. I think you should use ServiceLocator, but this is without empirical evidence; maybe someone can prove me wrong (?)

Class design: file conversion logic and class design

This is pretty basic, but sort of a generic issue so I want to hear what people's thoughts are. I have a situation where I need to take an existing MSI file and update it with a few standard modifications and spit out a new MSI file (duplication of old file with changes).
I started writing this with a few public methods and a basic input path for the original MSI. The thing is, for this to work properly, a strict path of calls has to be followed from the caller:
var custom = CustomPackage(sourcemsipath);
custom.Duplicate(targetmsipath);
custom.Upgrade();
custom.Save();
custom.WriteSmsXmlFile(targetxmlpath);
Would it be better to put all the conversion logic as part of the constructor instead of making them available as public methods? (in order to avoid having the caller have to know what the "proper order" is):
var custom = CustomPackage(sourcemsipath, targetmsipath); // saves converted msi
custom.WriteSmsXmlFile(targetxmlpath); // saves optional xml for sms
The constructor would then directly duplicate the MSI file, upgrade it and save it to the target location. The "WriteSmsXmlFile is still a public method since it is not always required.
Personally I don't like to have the constructor actually "do stuff" - I prefer to be able to call public methods, but it seems wrong to assume that the caller should know the proper order of calls?
An alternative would be to duplicate the file first, and then pass the duplicated file to the constructor - but it seems better to have the class do this on its own.
Maybe I got it all backwards and need two classes instead: SourcePackage, TargetPackage and pass the SourcePackage into the constructor of the TargetPackage?
I'd go with your first thought: put all of the conversion logic into one place. No reason to expose that sequence to users.
Incidentally, I agree with you about not putting actions into a constructor. I'd probably not do this in the constructor, and instead do it in a separate converter method, but that's personal taste.
It may be just me, but the thought of a constructor doing all these things makes me shiver. But why not provide a static method, which does all this:
public class CustomPackage
{
private CustomPackage(String sourcePath)
{
...
}
public static CustomPackage Create(String sourcePath, String targetPath)
{
var custom = CustomPackage(sourcePath);
custom.Duplicate(targetPath);
custom.Upgrade();
custom.Save();
return custom;
}
}
The actual advantage of this method is, that you won't have to give out an instance of CustomPackage unless the conversion process actually succeeded (safe of the optional parts).
Edit In C#, this factory method can even be used (by using delegates) as a "true" factory according to the Factory Pattern:
public interface ICustomizedPackage
{
...
}
public class CustomPackage: ICustomizedPackage
{
...
}
public class Consumer
{
public delegate ICustomizedPackage Factory(String,String);
private Factory factory;
public Consumer(Factory factory)
{
this.factory = factory;
}
private ICustomizedPackage CreatePackage()
{
return factory.Invoke(..., ...);
}
...
}
and later:
new Consumer(CustomPackage.Create);
You're right to think that the constructor shouldn't do any more work than to simply initialize the object.
Sounds to me like what you need is a Convert(targetmsipath) function that wraps the calls to Duplicate, Upgrade and Save, thereby removing the need for the caller to know the correct order of operations, while at the same time keeping the logic out of the constructor.
You can also overload it to include a targetxmlpath parameter that, when supplied, also calls the WriteSmsXmlFile function. That way all the related operations are called from the same function on the caller's side and the order of operations is always correct.
In such situations I typicaly use the following design:
var task = new Task(src, dst); // required params goes to constructor
task.Progress = ProgressHandler; // optional params setup
task.Run();
I think there are service-oriented ways and object-oritented ways.
The service-oriented way would be to create series of filters that passes along an immutable data transfer object (entity).
var service1 = new Msi1Service();
var msi1 = service1.ReadFromFile(sourceMsiPath);
var service2 = new MsiCustomService();
var msi2 = service2.Convert(msi1);
service2.WriteToFile(msi2, targetMsiPath);
service2.WriteSmsXmlFile(msi2, targetXmlPath);
The object-oriented ways can use decorator pattern.
var decoratedMsi = new CustomMsiDecorator(new MsiFile(sourceMsiPath));
decoratedMsi.WriteToFile(targetMsiPath);
decoratedMsi.WriteSmsXmlFile(targetXmlPath);

generic type dependency injection: How to inject T

I want to handle different types of docs the same way in my application
Therefore:
I have a generic interface like this.
public interface IDocHandler<T>where T: class
{
T Document { get;set;}
void Load(T doc);
void Load(string PathToDoc);
void Execute();
void Execute(T doc);
}
And for different types of documents I implement this interface.
for example:
public class FinanceDocumentProcessor:IDocumentHandler<ReportDocument>
{}
public class MarketingDocumentProcessor:IDocumentHandler<MediaDocument>
{}
Then I can do of course something like this:
IDocumentHandler<ReportDocument> docProc= new FinanceDocumentProcessor();
It would be interessting to know how I could inject T at runtime to make the line above loosly coupled...
IDocumentHandler<ReportDocument> docProc = container.resolve("FinanceDocumentProcessor());
but I want to decide per Configuration wether I want to have my FinanceDomcumentProcessor or my MarketingDocumentProcessor... therefore I would have to inject T on the left site, too ...
Since I have to use c# 2.0 I can not use the magic word "var" which would help a lot in this case... but how can I design this to be open and flexible...
Sorry for the misunderstanding and thanks for all the comments but I have another example for my challenge (maybe I am using the wrong design for that) ...
But I give it a try: Same situation but different Explanation
Example Image I have:
ReportingService, Crystal, ListAndLabel
Three different Reporting Document types. I have a generic Handler IReportHandler<T> (would be the same as above) this Handler provides all the functionality for handling a report Document.
for Example
ChrystalReportHandler:IReportHandler<CrystalReportDocument>
Now I want to use a Framework like Unity (or some else framework) for dependency injection to decide via configuration whether I want to use Crystal, Reportingservices or List and Label.
When I specify my mapping I can inject my ChrystalReportHandler but how can I inject T on the left side or in better word The Type of ReportDocument.
IReportHandler<T (this needs also to be injected)> = IOContainer.Resolve(MyMappedType here)
my Problem is the left Site of course because it is coupled to the type but I have my mapping ... would it be possible to generate a object based on Mapping and assign the mapped type ? or basically inject T on the left side, too?
Or is this approach not suitable for this situation.
I think that with your current design, you are creating a "dependency" between IDocumentHandler and a specific Document (ReportDocument or MediaDocument) and so if you want to use IDocumentHandler<ReportDocument or MediaDocument> directly in your code you must assume that your container will give you just that. The container shouldn't be responsible for resolving the document type in this case.
Would you consider changing your design like this?
public interface IDocumentHandler
{
IDocument Document { get; set; }
void Load(IDocument doc);
void Load(string PathToDoc);
void Execute();
void Execute(IDocument doc);
}
public class IDocument { }
public class ReportDocument : IDocument { }
public class MediaDocument : IDocument { }
public class FinanceDocumentProcessor : IDocumentHandler { }
public class MarketingDocumentProcessor : IDocumentHandler { }
If I understand you correctly, you have two options.
if you have interface IDocHandler and multiple classes implementing it, you have to register each type explicitly, like this:
container.AddComponent>(typeof(FooHandler));
if you have one class DocHandler you can register with component using open generic type
container.AddComponent(typeof(IDocHandler<>), typeof(DocHandler<>));
then each time you resolve IDocHandler you will get an instance of DocHandler and when you resolve IDocHandler you'll get DocHandler
hope that helps
You need to use a non-generic interface on the left side.
Try:
public interface IDocumentHandler { }
public interface IDocumentHandler<T> : IDocumentHandler { }
This will create two interfaces. Put everything common, non-T-specific into the base interface, and everything else in the generic one.
Since the code that you want to resolve an object into, that you don't know the type of processor for, you couldn't call any of the T-specific code there anyway, so you wouldn't lose anything by using the non-generic interface.
Edit: I notice my answer has been downvoted. It would be nice if people downvoting things would leave a comment why they did so. I don't care about the reputation point, that's just minor noise at this point, but if there is something seriously wrong with the answer, then I'd like to know so that I can either delete the answer (if it's way off target) or correct it.
Now in this case I suspect that either the original questionee has downvoted it, and thus either haven't posted enough information, so that he's actually asking about something other than what he's asked about, or he didn't quite understand my answer, which is understandable since it was a bit short, or that someone who didn't understand it downvoted it, again for the same reason.
Now, to elaborate.
You can't inject anything "on the left side". That's not possible. That code have to compile, be correct, and be 100% "there" at compile-time. You can't say "we'll tell you what T is at runtime" for that part. It just isn't possible.
So the only thing you're left with is to remove the T altogether. Make the code that uses the dependency not depend on T, at all. Or, at the very least, use reflection to discover what T is and do things based on that knowledge.
That's all you can do. You can't make the code on the left side change itself depending on what you return from a method on the right side.
It isn't possible.
Hence my answer.