I am reading the book You, I and ReactiveUI and my question relates to the source code for the book at https://github.com/kentcb/YouIandReactiveUI. The versions of ReactiveUI and Splat have changed since the code was published and one portion of the code cannot be duplicated in the current versions. I have contacted the author and am still waiting on a response as of this time of posting this question, and so I am submitting this question here.
In App.xaml.cs there is a call to a Registrations.cs class that passes the current mutable dependency resolver:
public App()
{
this.autoSuspendHelper = new AutoSuspendHelper(this);
Registrations.Register(Splat.Locator.CurrentMutable);
}
In the Registrations.cs class, there is a line that takes that IMutableDependencyResolver and calls GetService:
public static void Register(IMutableDependencyResolver container)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
}
I, too, would like to get the IVewLocator service, but IMutableDependencyResolver no longer has a GetService method.
So my question is, how should this code be modified to have the same functionality?
The Splat.Locator.Current is an IReadonlyDependenyResolver and that does have a GetService method. Should that be used instead? I wasn't sure if I should change to using Splat.Locator.Current in case there was a reason that Splat.Locator.CurrentMutable was used and wanted to make sure that if I changed to using Splat.Locator.Current that it would not introduce anything unexpected.
UPDATE:
Just want to add that, armed with the knowledge from DPVreony's answer that it is typically the same class implementing the two interfaces, I was able to implement some later lines in the Registrations.cs class that I needed.
So, further in that class, there are some lines that register constants. These needed the mutable dependency resolver. So you can just pass both the read only and mutable into the Registrations class and use them where needed, as shown below:
public static void Register(IReadonlyDependencyResolver container, IMutableDependencyResolver mutableContainer)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
mutableContainer.RegisterConstant(viewLocator, typeof(IViewLocator));
...
var defaultActivationForViewFetcher = container.GetService<IActivationForViewFetcher>();
...
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IActivationForViewFetcher));
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IForcibleActivationForViewFetcher));
}
And then call the method like so:
Registrations.Register(Splat.Locator.Current, Splat.Locator.CurrentMutable);
There was a change in Splat due to how some DI containers behave with registering services (i.e. they keep re-initializing). So get functionality was split off onto the IReadonlyDependenyResolver exposed by Splat.Locator.Current
It was to encourage the mindset of use the MutableLocator to get everything in place and then after that you should only ever need to read using Splat.Locator.Current so you're fine to use it. Typically it's the same class implementing the 2 interfaces, so it's a semantic change to reduce risks of tearing down the locator by mistake.
So in short yes Splat.Locator.Current is for GetService
Hope that all makes sense.
Related
To clarify my question, suppose I have the following very basic statistics interface and class:
public interface IStatistics
{
void IncrementPacketsDiscovered();
}
public class Statistics : IStatistics
{
private int numberOfPacketsDiscovered = 0;
public void IncrementPacketsDiscovered()
{
numberOfPacketsDiscovered++;
}
}
Then suppose I have the following class that receives the injected IStatistics object:
public class Reporter
{
private IStatistics _statistics;
public Reporter(IStatistics statistics)
{
_statistics = statistics;
_statistics.IncrementPacketsDiscovered();
}
}
Why is it that I am able to call the IStatistics method IncrementPacketsDiscovered() on the IStatistics object and it automatically knows to fetch the method definition that was implemented in the Statistics class?
Any help would be greatly appreciated. Thank you!
TLDR; because the injected object that implements IStatistics is an instance of the Statistics class, and it is this way because somewhere else you told the dependency resolver to use Statistics whenever you mention IStatistics..
Note that Statistics.IncrementPacketsDiscovered being called is nothing to do with DI per se, you could write this:
IStatistics x = new Statistics();
x.IncrementPacketsDiscovered();
On the outside, x looks like an IStatistics. On the inside, it is a Statistics. If Statistics did something else (other than just implement the interface) it would be easier to see. It would also probably be more clear what's going on if you had something else that implemented IStatistics, like some sort of FakeStatistics that you use in a test scenario - testing is one such valid reason where you'd switch your program back and forth between different suites of objects.
You could just conceive that somewhere outside of all your code is the dependency resolver, a thing created by Microsoft*. It did that first line of code above for you, and later when you said you wanted to have a Reporter it looked and saw "the constructor takes a parameter of anything that implements IStatistics, and I just happen to have an instance of Statistics here that fits that requirement, so I'll pass that into the Reporter constructor.." because that is what it is configured to do/that is its job.
If you had a FakeStatistics that you used for testing, and a context where you reconfigured the injector to create and supply fake objects then it suddenly starts to make sense why it's a useful way to engineer - you don't have to have 100 places where you said new Statistics where you go through and change them all to say new FakeStatistics. It's also useful to be writing a class and suddenly realize "this class needs statistics.." you add a single argument IStatistics x to the constructor, hit Ctrl . and pick the option to add a property for it and that class now has access to a suitable implementation of IStatistics, supplied by the resolver. You don't have to chase up through everywhere you said new MyXClass(param1, param2) and change it to say new MyXClass(param1, param2, someStatistics) because the job of newing all your objects is the responsibility of the resolver
By using interfaces and coding up such that "any object that implements this interface can sensibly be used as an input argument to this class" you then open it up to the possibility that a "class instance lookup and provider service" can wire all your app together just by "rummaging around in its currently configured bag of objects for one that will do the job" (and then you change what's in the bag depending on the context)
So where did you put things in the bag? In the part of the program where you configured the resolver, methods like AddScoped, AddTransient, AddSingleton have the dual purpose of mapping a type of class to a type of interface and also configure what sort of lifetime the instance has- resolvers manage instances for you and create/destroy them over the lifetime you specify by which Add* method you use
* With this statement I am, of course, making a gross assumption as to which injector you're using. There are other DI/IoC frameworks available for C#, created by others. The overarching concept remains the same; the more you can get the computer to write your code for you, the quicker, easier and more reliable it can be. Establishing dependenceies between objects in your program is one such place where it can make sense to hand it off to software rather than writing it yourself
I come across this regularly when refactoring code. Say I have a base class and I read some configuration parameters and stuff them into properties like this
public BaseClass()
{
_property1 = ConfigurationManager.AppSettings["AppSetting1"];
_property2 = ConfigurationManager.AppSettings["AppSetting2"];
_property3 = ConfigurationManager.AppSettings["AppSetting3"];
}
And then I call a method in another class like this
OtherClass otherClass = new OtherClass();
var foo = otherClass.SomeMethod(_property1, _property2, _property3);
Is it better to do that? What if I only needed the AppSettings values inside of the OtherClass class? then I could just load them up as private props and initialize them in the constructor and the referencing class/caller wouldn't need to be concerned with the settings.
public OtherClass()
{
_property1 = ConfigurationManager.AppSettings["AppSetting1"];
_property2 = ConfigurationManager.AppSettings["AppSetting2"];
_property3 = ConfigurationManager.AppSettings["AppSetting3"];
}
My implementation would then simply be
OtherClass otherClass = new OtherClass();
var foo = otherClass.SomeMethod();
This one bugs me but I am not really sure why. Which is a better practice and why? And I apologise I am missing something obvious. It happens sometimes lol.
Thanks -Frank
In my view, it depends on what goal of your class.
If class belongs to domain classes, so there is no need to have a dependency to ConfigurationManager class. You can create a constructor and supply necessary data:
public class FooClass()
{
public Property1 {get; private set;}
public FooClass(string property1)
{
Property1 = property1;
}
}
If FooClass belongs to Service Layer, then, in my view, it is eligible to have a dependency to ConfigurationManager class.
I can't really comment on "better" as that's quite subjective, but it's at the very least factual to say that passing the parameters into the method, rather than having the method go and get them itself, is a form of dependency injection. Dependency injection has advantages in that it reduces the number of things the class has to know how to do/reduces the number of other classes any given class needs to do its work. Typically in OO design we look for ways to reduce the dependencies a class has on other classes. You might also see the concept referred to in general as low coupling. Classes that are not highly coupled to other classes are easier to reuse as independent modules within multiple programs
In your example, OtherClass (and/or BaseClass) needs to know what a ConfigurationManager is, which means it needs a reference to its namespace, needs to have system.configuration.dll available on the target etc just so that it can go and get some basic things (strings) that contain info necessary to do its work. If you instead give the strings to the method then it can do its work without knowing what a ConfigurationManager is - you can use it in an app that doesn't even have a ConfigurationManager anywhere, maybe because it gets its config from a database or perhaps it's part of a unit test that gets some contrived data directly from hard coding to ensure a given result is always obtained
When you're down with the concept that the data a class needs to do its work can come from above it starts to make more sense why systems that pass data around like this can work with an inversion-of-control container; essentially software that creates instances of objects for you according to some preconfigured rules about where to get the data that should be passed in. An IoC container can look at an object and decide what arguments to pass to (e.g. its constructor) based on a consistent set of rules, and take another step towards removing dependencies by further reducing use of the word "new". Think of it like writing a config file to describe which of your objects need what instances of other classes to do the work. You craft your IoC container setup so it makes one IniFileConfigSettingsProvider instance and then provides that instance to any object that needs some kind of IConfigSettingsProvider to do its work. Later you switch away form ini files and go to Xml files. You create a class called XmlFileConfigSettingProvider, register it with the IoC and it becomes the new instance that is passed to any class needing an IConfigSettingsProvider. Critically, you made another class, registered it with the IoC and then it gets used throughout your program but you never made an instance of it yourself
If you ever heard the phrase "new is glue" concepts like this are generally what it alludes to - when your OtherClass says var x = new ConfigurationManager... x.Settings["a"].... the use of the word new has suddenly hard wired it to needing a ConfigurationManager; it can't function without knowing what it is. The strive these days is generally to have a class accepting a "passed-in provider of settings that complies with some interface" or "passed-in primitives that are settings" - things that are either implementation specific but obey a generic interface, or ubiquitous in the language and need no special imports respectively. Perhaps either of your mentioned approaches bug you because deep down you feel that neither of them need to depend on ConfigManager; whether they both need settings or not, they can get them passed in, from something higher up the chain that should be making the decisions as to what settings to use
There will be pros and cons of every design and coding choice. As they say, same pattern may not fit everyone. So one has to customize based on need.
Mainly, decision should be based on use cases of your application. Let me provide few scenarios to describe it. Suppose items configured in AppSettings will not change in life-time of the your application then you can have an approach in which dependencies with AppSettings are least. In particular an approach as var foo = otherClass.SomeMethod(_property1, _property2, _property3);. This matches with OOD principles as classes will focus on business logic.
But if you see add/modifying/deleting items (even in rare situations) during life time then above approach would be difficult to maintain. For example without restarting your application/WebServer if AppSettings needs to be reloaded based on certain conditions. One may argue why such settings will be kept in AppSettings, which is very valid too. If your application demands such scenarios then it would be better to use ConfigurationManager.AppSettings without worrying about dependencies. One can opt to extend it have wrapper class (Singleton pattern) to manage and provide access to ConfigurationManager.AppSettings.
I have seen lots of examples on how to do this, but as I am a newbie to DI, I thought it best to ask a question specifically for my issues. Again, I apologize if this has been asked already.
We have a C# WCF service that is working, but I have recently been asked to implement a DI framework for reuse ability. After looking around I have chosen Simple Injector.
So my service currently compiles and I can view the WSDL from a browser.
To start I have placed the initialization code that sets up the container in a Global.asax file in the Application_Start function. Within this function I have the following code:
var container = new Container();
container.Options.DefaultScopedLifestyle = new WcfOperationLifestyle();
followed by my registrations:
container.Register<IPersonManager, PersonManager>();
etc....
finally, I run:
SimpleInjectorServiceHostFactory.SetContainer(container);
This runs correctly, no errors and I can break point onto the fisrt line above and step through the code.
I have been told that I should use a different location for the initialization code and not use a global.asax file. Not sure if I should change this.
OK.
When I look at the constructor for the PersonManager class, I am passing an object that also implements the IPersonManager interface.
I am assuming this is the correct way of doing this. So as long as the object implements the IPersonManager interface it will be injected in. Not sure about this either
Anyway,
I have a class, the code is as follows:
public static class AddressRepository
{
public static void SetAddress(this IRepository<Address> AddressRepository)
{
throw new NotImplementedException();
}
}
And I have tried to set the Simple Injector initialisation for this as follows:
container.Register(typeof(IRepository<>), typeof(Address), Lifestyle.Scoped);
This does not work. I guess because the AddressRepository does not implement an interface, but the method does.
Is it possible to inject into this method and if so how is it done.
Can someone please explain to me the notion of a Unity Container like I'm a 6 year old kid? How does it work and what does it do?
This is a more technical description of the background, I hope you still find it useful.
Generally put, it is a DI (dependency injection) container.
Given the following class:
public class Sample
{
Service a;
public Sample()
{
a = new Service();
}
}
The problem with that is that it initializes its own version of Service, making it very hard to adjust for code changes (ie. if you want to exchange Service with something different). Also it makes testing difficult.
To resolve that, don't actually create it yourself, but get it from the outside:
public class Sample
{
Service a;
public Sample(Service aService)
{
a = aService;
}
}
Now you have taken the creation away from the class you can just put it in there from the outside, increasing testability and maintainability. However, you still have a dependency on the class Service. You aren't really interested in that specific class, but in the behaviour it offers - so you make in interface out of it.
public class Sample
{
IService a;
public Sample(IService aService)
{
a = aService;
}
}
Now, you can replace the service with anything you like. For example, you have a class getting data from a server using a service. Now, you want to test only the data parsing and not the data fetching service - just create a class implementing the interface, serving static data - done!
Now, Unity comes into play. At the moment, you have to resolve the dependencies yourself. What unity does is simple - it takes all classes that have dependendencies and resolves those - so you can just call (pseudocode, I don't know unity):
UnityContainer uc = new UnityContainer();
var a = uc.GetService<IService>();
And it gets you the readily useable class.
What do we have achivied by that?
the code is more maintainable because you don't rely on specific types
the code is more testable
the application is easily expandable
As a summary: it helps creating better applications faster.
Unity Container is like a jar full of cookies , when you need a cookie you just ask jar to give you a cookie.
Each cookie is having some virtues like you can have a cookie but you can't eat it because it is very hard to eat (something like singleton)
when your mom creates a new cookie , she just put that cookie in the jar rather than giving you directly!
I recommend you to watch Mike Taulty's Prism video series
The first two chapters will answer your question, and you can watch the other chapters to learn Prism (although its version 2 and quite old, the basic principles remains the same...)
Good luck :)
I'm still struggling a bit with OOP concepts and dependency injection so bear with me.
I have generated my Linq2Sql model with a User table and now I would like to be able to send a confirmation email to this user so I created a partial class file for my User object and I felt it was natural to add a SendConfirmationEmail() method to the User class. This method will use a MailService to send the actual email and I would like to use dependency injection to pass in the service so I created a constructor overload on the User object like this
public User(IMailService service) : this()
{
_service = service;
}
The SendConfirmationEmail method would look like this
public void SendConfirmationEmail()
{
_service.SendMail(params...);
}
I realize this is a kind of poor mans dependency injection and I hope to switch to a dependency injection framework later as I am getting more grips on this.
The problem for me is that I need to make a reference from my model dll to my service dll which does not seem right and because I am unsure of how nice my linq2sql generated entities plays with Dependency injection frameworks and OOP concepts (I think ninject looks most promising).
I was hoping someone with a bit more experience than me could tell I'm if I am going in the right direction with this. I know I can make it work but I would like to educate my self in doing it in the correct way in the same step.
I personally would change some things in your architecture:
I don't think that SendConfirmationEmail should be a method on your User object. But should be a method on another object with the user as a parameter. (this also better seperates your Dal from the other logic.
Second in this method use something like this:
Services.Get<IMailService>().SendMail(params ...);
You can implement Services as the folowin (just an example):
public class Services
{
protected static Dictionary<Type, object> services = new Dictionary<Type, object>();
private Services()
{
}
static Services()
{
// hard coded implementations...
services.Add(typeof(IMailService), new DefaultMailServiceImplementation());
}
public static T Get<T>() where T : class
{
Type requestedType = typeof(T);
return services[requestedType] as T;
}
}
By using a "Services"-class (or call it what you like) you add an additional layer between the IOC-framework and your code which makes it easy to change IOC-frameworks. Just change the implementation in the Get method to use one. You can also use a hardcoded temporary solution (until you use an IOC-framework) in the static constructor (like I did in the above example).
The problem with that approach is that much of the time the entity is going to come from the LINQ-to-SQL back-end, and so isn't going to use your constructor (LINQ-to-SQL creates objects in its own way; you cannot force LINQ-to-SQL to use your constructor) - so this would only be useful for the (few) objects you create yourself. Data-binding (etc) will also commonly use the parameterless constructor by default.
I wonder if this wouldn't work better as a utility method that accepts the service, or obtains the service itself via a factory / singleton.
I think you're ok doing this, but you might want to do two additional things to protect yourself from future cross-layer dependency problems:
Create an interface for your User
object. You should do this because
not doing so will mean that
everything that consumes this
business object will have to
reference the LINQ dlls
unnecessarily.
Move your dependency injection from
the constructor into a property.
You do this because constructor
injection tends to limit your
ability to dynamically create your
object. Doing this, though poses a
problem, since you would have to
implement a lot of null checking
code for _service. You can fix this
by creating an "empty"
implementation of IMailService and
make it the default value for
_service.