Elegantly handling base class dependencies - c#

In the project I'm working on, I've added a base ViewModel class which contains some functionality and dependencies common to all ViewModels. It provides validation, messaging, dispatching and navigation services through the following properties:
IValidateProperties Validator { get; }
IMessenger Messenger { get; }
IDispatcherHelper DispatcherHelper { get; }
INavigationService Navigation { get; }
I use an IoC container to wire my dependencies, however I have a few options for how to handle these dependencies which are common to all of my ViewModels:
Inject them in the constructor. If I did this, then it would require adding these four arguments to the constructor of every single ViewModel and pass them to the base constructor. That's a lot of extra noise added to my code base, which I'd really rather avoid. Also, if I were to add another dependency at some point, that would require changing the constructor of every single ViewModel.
Use property injection. This is the approach I'm working with now. Unfortunately, it means not being able to access these properties until after the ViewModel has been constructed, resulting in the following workarounds:
private IValidateProperties _validator;
public IValidateProperties Validator
{
get => _validator;
set
{
_validator = value;
_validator.ValidationTarget = this;
}
}
private IMessenger _messenger;
public IMessenger Messenger
{
get => _messenger;
set
{
_messenger = value;
MessengerAttached();
}
}
protected virtual void MessengerAttached() { }
Make the properties static and inject them on app startup. This is easy for Messenger, DispatcherHelper and Navigation because they are used as singletons anyway. For Validator, I would need to add a static ValidatorFactory, and instantiate the Validator in the constructor using the factory. This way seems to be the cleanest way to do things, but I have this voice in the back of my head telling me that using statics like this is a bad idea.
I feel like option 1 is out of the question because of the large amount of noisy boilerplate code it would result in being added to my ViewModels. I'm still unsure whether 2 or 3 is the best way to go though. Is there a good reason that using statics is a bad idea in this case, or am I fretting over nothing?
Some people argue that statics lead to untestable code, but in this case it would actually make things easier to test. If I were to go with option 3, I could add the following class for all of my view model tests to inherit:
public abstract class ViewModelTestBase
{
protected readonly IValidateProperties ValidatorMock;
protected readonly IMessenger MessengerMock;
protected readonly IDispatcherHelper DispatcherHelperMock;
protected readonly INavigationService NavigationMock;
protected ViewModelTestBase()
{
ValidatorMock = Substitute.For<IValidateProperties>();
ViewModelBase.Validator = ValidatorMock;
MessengerMock = Substitute.For<IMessenger>();
ViewModelBase.Messenger = MessengerMock;
DispatcherHelperMock = Substitute.For<IDispatcherHelper>();
ViewModelBase.DispatcherHelper = DispatcherHelperMock;
NavigationMock = Substitute.For<INavigationService>();
ViewModelBase.Navigation = NavigationMock;
}
}
So, what concrete reasons are there for not going with approach #3? And if statics really are such a bad idea in this case, what concrete reasons are there for not going with approach #2 instead?

Related

Injecting parents into composite constructors with Unity C#

I am trying to get IoC working with Unity in C# with the idea of a passing a wrapper/composite class into the children.
The top level class that composes multiple classes provides some common functionality that the composed classes require access to.
To illustrate:
// The top composite class
public class Context : IContext {
public ISomething SomethingProcessor { get; }
public IAnother AnotherProcessor { get; }
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.AnotherProcessor = processor;
}
// A function that individual classes need access to, which itself calls one of the children.
public string GetCommonData() {
return this.AnotherProcessor.GetMyData();
}
}
public class Something : ISomething {
private _wrapper;
public Something(IContext context) {
this._wrapper = context;
}
// This class has no knowledge of IAnother, and requests data from the master/top class, which knows where to look for whatever.
public void Do() {
Console.WriteLine(_wrapper.GetCommonData());
}
}
public class Another : IAnother {
public string GetMyData() {
return "Foo";
}
}
If you didn't use IoC, it's easy, as the constructor for the Context class becomes:
public Context() {
this.SomethingProcessor = new Processor(this);
this.AnotherProcessor = new Another();
}
But when you're using IoC, the idea of "this" doesn't exist yet because it is yet to be constructed by the injector. Instead what you have a is a circular dependency.
container.RegisterType<ISomething, Something>();
container.RegisterType<IAnother, Another>();
container.RegisterType<IContext, Context>();
var cxt = container.Resolve<IContext>(); // StackOverflowException
The above example has been greatly simplified to illustrate the concept. I'm struggling to find the "best practice" way of dealing with this kind of structure to enable IOC.
Factory pattern is a way construct an object based on other dependencies or logical choices.
Factory Method: "Define an interface for creating an object, but let
the classes which implement the interface decide which class to
instantiate. The Factory method lets a class defer instantiation to
subclasses" (c) GoF.
Lots of construction.. hence the name Factory Pattern
A crude code sample that could be used with DI
public class ContextFactory : IContextFactory {
_anotherProcessor = anotherProcessor;
public ContextFactory(IAnotherProcessor anotherProcessor) {
//you can leverage DI here to get dependancies
}
public IContext Create(){
Context factoryCreatedContext = new Context();
factoryCreatedContext.SomethingProcessor = new SomethingProcessor(factoryCreatedContext )
factoryCreatedContext.AnotherProcessor = _anotherProcessor;
//You can even decide here to use other implementation based on some dependencies. Useful for things like feature flags.. etc.
return context;
}
}
You can get away with this, maybe? - but there is still the cyclic reference issue here and I would never commit this kind of code.
The problem here you need to concentrate on Inversion Of Control of that GetCommonData
Your SomethingProcessor should not rely on methods in another class. This is where In Inheritance could be used but Inheritance can become very complicated very quickly.
The best way forward is to Identify the ONE thing that is needed by both or many other places and break that out into a new Dependency. That is how you Invert Control.
TIP:
Don't overdo Interfaces- Use Interfaces where you think you will be working with Polymorphism, such as a collection of different objects that must promise you they have implemented a specific method/property. Otherwise you are over using Interfaces and increasing complexity. DI doesn't have to use Interfaces it can be a concrete implementation. Interfaces on Repositories are a good use since you can switch Databases out easily but Interfaces a factory like this is not really needed.
I don't know the name of this pattern, or even if it is a bad or good practice, but you can solve your problem of "double-binding" by creating a method to bind the "IContext", instead of doing it in the constructor.
For instance,
1) ISomething has a void BindContext(IContext context) method
2) You implement it as such :
class Something : ISomething
{
IContext _wrapper;
// ... nothing in constructor
public void BindContext(IContext context)
{
_wrapper = context;
}
}
3) Remove the IContext dependency injection in Something constructor.
And you call it from the context constructor :
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.SomethingProcessor.BindContext(this);
// same for IAnother
}
And you do the same for IAnother. You could even extract some common interface "IBindContext" to make things a beat more "DRY" (Don't Repeat yourself) and make IAnother and ISomething inherit from it.
Not tested, and again : not sure it's the best way to do such dependency design. I'll be glad if there is another answer which gives a state-of-the-art insight about this.

How to bind decorators with Ninject from outside in?

I use ninject bindings with WhenInjectedInto<> to bind decorators from inside out. However, from different entry points I need different features, maybe run in different sequence, so I would like to bind the decorators chain from outside in. Is this possible with Ninject?
Eg. I would live to achieve this:
Bind<IFooService>().To<SimpleService>().WhenInjectedInto<FeatureAFooServiceDecorator>();
Bind<IFooService>().To<FeatureAFooServiceDecorator>().WhenInjectedInto<FeatureBFooServiceDecorator>();
Bind<IFooService>().To<FeatureBFooServiceDecorator>().WhenInjectedInto<EntryPoint1>();
Bind<IFooService>().To<SimpleService>().WhenInjectedInto<FeatureBFooServiceDecorator>();
Bind<IFooService>().To<FeatureBFooServiceDecorator>().WhenInjectedInto<EntryPoint2>();
But this is not correct, because FeatureBFooServiceDecorator is not clear what it will get injected (FeatureAFooServiceDecorator or SimpleService).
I suppose the solution would be to get things binded the other way round like:
pseudocode
For<EntryPoint1>().Use<FeatureBFooServiceDecorator>().ThenUse<FeatureAFooServiceDecorator>().ThenUse<SimpleService>();
For<EntryPoint2>().Use<FeatureBFooServiceDecorator>().ThenUse<SimpleService>();
Edit:
To achieve this manually, I would do:
var entryPoint1 = new EntryPoint1(new FeatureBFooServiceDecorator(new FeatureAFooServiceDecorator(new SimpleService)));
var entryPoint2 = new EntryPoint2(new FeatureBFooServiceDecorator(new SimpleService));
(Of course I would avoid newing up things, because these classes have couple of more dependencies each, some of which are InRequestScope or InNamedScope)
Note: For the above example, asume that there are these classes:
public interface IFooService {/*...*/}
public class SimpleService : IFooService {/*...*/}
public class FeatureAFooServiceDecorator : IFooService
{
private readonly IFooService _innerFooService;
public FeatureAFooServiceDecorator(IFooService fooService) {
_innerFooService = fooService;
}
}
public class FeatureBFooServiceDecorator : IFooService {/*...same as above...*/}
public class EntryPoint1{
public EntryPoint1(IFooService fooService){/*...*/}
}
public class EntryPoint2{
public EntryPoint2(IFooService fooService){/*...*/}
}
So i gather what you want to do is
public class FeatureBFooService : IFooService
{
public FeatureBFooService(IFooService service1, IFooService service2)
{ ...}
}
var service = new FeatureBFooService(new FeatureAFooService(), new SimpleService());
(of course you don't want to do the new's yourself). So you are using the same interface multiple times, even for the same constructor, but want not only different instances but different types (FeatureAFooService, SimpleService) injected into the constructor of FeatureBFooService.
There's two ways i can think of how you can achieve this.
But to be honest, i ought to warn you that this seems quite complicated. Usually this means the design is not ideal and you'd be better of thinking about how to solve the problem differently. After all, when the implementation share the same interface, shouldn't they be doing about the same thing? It would be one thing to inject a collection of IFooService into a class whose using all these services, but that that class itself again is a IFooService seems a bit strange.
But enough said, i believe in people making their own choices - and sometimes mistakes - because that's the best way to learn. And of course i may also be wrong in my assumptions and what you're striving for is the best achievable solution.
Solution 1: .ToConstructor() binding
Bind<IFooService>().ToConstructor(ctorArg => new FeatureBFooService(ctorArg.Inject<FeatureAFooService>(), ctorArg.Inject<SimpleService>()));
for every constructor parameter you can define what should get injected. This way you don't rely on a binding and can determine what get's injected for a given type.
Solution 2: [Named] binding
adapt the implementation as follows:
public const string FeatureAService = "FeatureA";
public const string SimpleService = "Simple";
public class FeatureBFooService : IFooService
{
public FeatureBFooService(
[Named(FeatureAService)]I FooService service1,
[Named(SimpleService] IFooService service2)
{ ...}
}
Bind<IFooService>().To<FeatureAService>().Named(FeatureAService);
Bind<IFooService>().To<SimpleService>().Named(SimpleService);
Solution 3: .ToProvider() binding + custom binding logic
What you could also do, is to do
Bind<IFooService>().ToProvider<FooServiceProvider>();
where FooServiceProvider will - according to you custom logic - decide what exact dependency is to be instanciated. It could then either do
IResolutionRoot.Get<FeatureAFooService>();
or you could still make use of the [Named] feature:
IResolutionRoot.Get<IFooService>(FeatureAService);
It could then, for example, look like (pseudo code):
public class FooServiceProvider : Provider<IFooService>
{
protected override IFooService CreateInstance(IContext context)
{
Type returnType = DetermineImplementationType(context);
switch(returnType)
{
case typeof(FeatureBFooService):
return CreateFeatureBFooService(context);
break:
default:
throw new NotSupportedException(...);
}
}
private static Type DetermineImplementationType(IContext context)
{
// your custom logic here
}
private static IFooService CreateFeatureBFooService(IContext context)
{
var dependency1 = context.Kernel.Get<IFooService>(FeatureAFooService);
var dependency2 = context.Kernel.Get<IFooService>(SimpleService);
return context.Kernel.Get<IFooService>(
FeatureBFooService,
new ConstructorArgument("service1", dependency1),
new ConstructorArgument("service2", dependency2));
}
}
Note that with ConstructorArgument, the value is injected into the constructor parameter matching the name (service1, service2), so that's a refactor-trap.
Also note that you can also use IContext.Kernel.ContextPreservingGet<> if you need to preserve the context. However, that's only available with the extension ninject.extensions.ContextPreservation.

How do I wire an IoC Container to pass a value to a factory method to resolve?

Background / Goal
We have several "client sites" on our web app that users can switch between
We do a lot of wiring up of objects based on factories that take in the client site ID and create an instance
I would like to inject these dependencies into the classes instead
I also want to make sure I can pass in my own implementations to the constructor for the purposes of unit testing.
We have initially elected to use StructureMap 3.x to do so, but are open to alternatives if they can help us solve this scenario gracefully.
Question
In instances where I require a different dependency based on a client site ID that I'll only get at run-time, what is the appropriate way to set up an IoC container and the appropriate way to request the object from it in order to make it as painless as possible?
Am I thinking about this wrong and unintentionally creating some sort of anti-pattern?
Example Code
Normally we're doing something like the following coming in:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = new dependentObjectFactory(clientSiteID).GetDependentObject();
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
What I'd like to do:
public class MyService
{ DependentObject _dependentObject;
public MyService(int clientSiteID)
{
// ...
_dependentObject = MyTypeResolver.GetWIthClientContext<IDependentObject>(clientSiteID);
}
public MyService(int clientSiteID, IDependentObject dependentObject)
{
// ...
_dependentObject = dependentObject;
}
public void DoAThing()
{
//...
_dependentObject.DoSomething();
}
}
I would set up the IoC container in such a way that I can use my MyTypeResolver to pass in the clientSiteID, and have the container call my DependentObjectFactory and return the correct object result.
I'm new to IoC containers, and while I'm trying to plow through the literature, I have the feeling it may be easier than I'm making it so I'm asking here.
Probably the simplest way to do this is to use an Abstract Factory. Most IOC frameworks can auto-create them for you, but here's how you can do it manually (I always prefer to do it manually first so I know it works, and then you can check out how the framework can help you automagic it)
Now one thing to mention - I would recommend a slight readjustment of how the final solution works, but I'll go into that once I have shown how it can currently work. Example below assumes Ninject and please excuse any typos, etc.
First create an interface for your dependency
public interface IDependentObject
{
void DoSomething();
}
Then declare empty marker interfaces for each specific implementation of IDependentObject
public interface INormalDependentObject:IDependentObject{};
public interface ISpecialDependentObject:IDependentObject{}
and implement them:
public class NormalDependentObject:INormalDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something}
}
public class DependentObject:ISpecialDependentObject
{
readonly int _clientID;
public DependentObject(int clientID)
{
_clientID=clientID;
}
public void DoSomething(){//do something really special}
}
and of course as you mentioned you may have many more implementations of IDependentObject.
There may be a more elegant way of allowing your IOC framework to resolve at runtime without having to declare the marker interfaces; but for now I find it useful to use them as it makes the binding declarations easy to read :)
Next, declare an interface and implementation of an IDependentObjectFactory:
public interface IDependentObjectFactory
{
IDependentObject GetDependenObject(int clientID);
}
public class DependentObjectFactory: IDependentObjectFactory
{
readonly _kernel kernel;
public DependentObjectFactory(IKernel kernel)
{
_kernel=kernel;
}
public IDependentObject GetDependenObject(int clientID)
{
//use whatever logic here to decide what specific IDependentObject you need to use.
if (clientID==100)
{
return _kernel.Get<ISpecialDependantObject>(
new ConstructorArgument("clientID", clientID));
}
else
{
return _kernel.Get<INormalDependentObject>(
new ConstructorArgument("clientID", clientID));
}
}
}
Wire these up in your Composition Root:
_kernel.Bind<INormalDependentObject>().To<NormalDependentObject>();
_kernel.Bind<ISpecialDependentObject>().To<SpecialDependentObject>();
_kernel.Bind<IDependentObjectFactory>().To<DependentObjectFactory>();
and finally inject your factory into the service class:
public class MyService
{
IDependentObject _dependentObject;
readonly IDependentObjectFactory _factory;
//in general, when using DI, you should only have a single constructor on your injectable classes. Otherwise, you are at the mercy of the framework as to which signature it will pick if there is ever any ambiguity; most all of the common frameworks will make different decisions!
public MyService(IDependentObjectFactory factory)
{
_factory=factory;
}
public void DoAThing(int clientID)
{
var dependent _factory.GetDependentObject(clientID);
dependent.DoSomething();
}
}
Suggested changes
One immediate change from your structure above is that I have left clientID out of the service constructor and moved it to a method argument of DoAThing; this is because it makes a bit more sense to me that the Service itself would be stateless; of course depending on your scenario, you may want to not do that.
I mentioned that I had a slight adjustment to suggest , and it's this; the solution above depends (no pun!) on implementations of IDependentObject having a constructor with this signature:
public SomeDependency(int clientID)
If they don't have that signature then the factory won't work; personally I don't like my DI to have to know anything about constructor params because it takes you out of purely dealing with interfaces and forcing you to implement specific ctor signatures on your concrete classes.
It also means that you can't reliably make your IDependentObjects be part of the whole DI process (i.e whereby they themselves have dependency graphs that you want the framework to resolve) because of the forced ctor signature.
For that reason I'd recommend that IDependentObject.DoSomething() itself be changed to DoSomething(int clientID) so that you can elide the new ConstructorArgument part of the factory code; this means that your IDependentObject s can now all have totally different ctor signatures, meaning they can have different dependencies if needs be. Of course this is just my opinion, and you will know what works best in your specific scenario.
Hope that helps.

Two services dependend on eachother (stackoverflow exception) - how to solve?

I am new to dependency injection, and I am trying to solve an issue. I have two services. Each of these services have methods who need eachother.
For instance: SiteManager have methods where it needs my ForumManager. My ForumManager have methods where it needs my SiteManager.
I have the following two classes:
public class SiteManager:ISiteManager
{
public IForumManager ForumManager { get; set; }
public SiteManager()
{
this.ForumManager = new ForumManager();
}
}
public class ForumManager:IForumManager
{
public ISiteManager SiteManager { get; set; }
public ForumManager()
{
this.SiteManager = new SiteManager();
}
}
Very obviously this will result in a stack overflow exception, as they call eachother. I've read a lot of posts here, and I think I just need a small hint on how to solve this. I have my interfaces in their own assembly.
I thought about putting the dependencies in their own property so when they are used, they are made. However, is this best practice?
I do not use an IoC container (and I haven't used that before).
Any hints on how to solve this particular issue in a "best practice" way! :-)
You should not be calling new within your classes, that will tightly couple them. The correct pattern for IOC that will allow you to test each class separately using mocks is:-
public class SiteManager:ISiteManager
{
private readonly IForumManager forumManager;
public SiteManager(IForumManager forumManager)
{
this.forumManager = forumManager;
}
}
public class ForumManager:IForumManager
{
private readonly ISiteManager siteManager;
public ForumManager(ISiteManager siteManager)
{
this.siteManager = siteManager;
}
}
But, that doesn't solve the mutual recursion. The easiest way to solve that is to not use constructor injection for one of the classes, but use property injection instead, i.e. put the SiteManager back to a public property on the ForumManager and set it after creating both objects.
Your setup code then does:-
IForumManager forumManager = new ForumManager();
ISiteManager siteManager = new SiteManager(forumManager);
forumManager.SiteManager = siteManager;
Another alternative would be to pass a ForumManagerFactory into the SiteManager, e.g. a Func<ISiteManager,IForumManager>.
ISiteManager siteManager = new SiteManager((s) => new ForumManager(s));
Inside the site manager you can then call the Func, passing this to get the IForumManager. The ForumManager gets an instance of the SiteManager and the SiteManager has the ForumManager object.
When using MVP with winforms and AutoFac, I had this exact same issue with the view referencing the presenter and the presenter referencing the view. The way I got around it is to have one of your classes pass itself to the other using an Initialize method. I am not sure if this is best practice, but I have seen it suggested before (this question about mvp)
So for the implementation details:
public class SiteManager:ISiteManager
{
public IForumManager ForumManager { get; set; }
public SiteManager()
{
}
public Initialize(IForumManager forumManager)
{
ForumManager = forumManager
}
}
public class ForumManager:IForumManager
{
public ISiteManager SiteManager { get; set; }
public ForumManager(ISiteManager siteManager)
{
this.SiteManager = new SiteManager();
this.SiteManager.Initialize(this);
}
}
Edit Actually would probably go with the other solutions posted, I was just looking at this purely from a circular dependency point of view
what you are doing and what you are suggesting both will cause stack overflow exception. i don't know why will you want to do something like that and you are not giving any hints on that but i guess i can offer you to create a manager, maybe a singleton, maybe just with static method and do:
public static void DoStuff(ISiteManager sm, IForumManager fm)
{
// your code here can use the best of both without SO
}
and not holding ISiteManager in ForumManager and IForumManager in SiteManager
You clearly can't have interdependant classes. What you need to do is to create a separate class and move there the methods which use the same time forum manager and sitemanger: Here is a sample 3rd class:
class ForumAndSiteManager
{
public ForumAndSiteManager(ISiteManager siteMaanger, IForumManager forumManager)
{
//save the injected object to private fileds
}
//define methods which will use both sitemanager and forum manager
}
This way you will brake the circular depedency
You should definitely avoid circular dependencies. I mean A depends on B and B on A.
This is like a cancer of your context dependencies. We used spring.net framework which contrary to java's version is unable to switch on a failing system if it discovers this kind of dependency. I have to say that this brings us only mess and hours of spring's logs searching and analyzing.
We defined almost 200 without any problem but once we added just another bean along with Lazy reference it failed down. This is almost impossible to untangle our solution to avoid it right now so we hook and hook and hook whilst it fails :-(

Register a type with primitive-arguments constructor?

I have a class that has in its constructor some primitive type arguments, such as string etc.
How should I register the type with unity container?
public LoginManager(
IRegionManager regionManager,
IEventAggregator eventAggregator,
string mainRegionName,
Uri login,
Uri target)
{
this.regionManager = regionManager;
this.eventAggregator = eventAggregator;
this.mainRegionName = mainRegionName;
this.login = login;
this.target = target;
}
}
Update:
Remeber that the IRegionManager and the IEventAggregator are known types to the Prism UnityBootstrapper which is the container wrapper in my case. Do I have to re-register them?? I want to keep the type-registration as simple as possible.
Would this be considered a bad habit? Any better alternatives?
Try to prevent to have a class design that has primitive or hard to resolve types in the constructor. As you have already seen from Tavares' answer, you're configuration gets very brittle (update: Tavares seems to have removed his answer for reasons that are not clear to me). You loose compile time support, and every change to that constructor would make you change your DI configuration.
There are multiple ways to change your design to prevent this. Which one is applicable for you is up to you, but here are a few ideas:
Option 1: Use an immutable configuration DTO:
private sealed class LoginManagerConfiguration
{
public Uri Login { get; private set; }
public Uri Target { get; private set; }
public string MainRegionName { get; private set; }
public LoginManagerConfiguration(Uri login, Uri target, string mainRegionName)
{
this.Login = login;
this.Target = target;
this.MainRegionName = mainRegionName;
}
}
Now you can let your LoginManager take a dependency on LoginManagerConfiguration:
public LoginManager(IRegionManager regionManager,
IEventAggregator eventAggregator,
LoginManagerConfiguration configuration)
{
...
}
The LoginManagerConfiguration can simply be registered like this:
container.RegisterInstance<LoginManagerConfiguration>(
new LoginManagerConfiguration(
login: new Uri("Login"),
target: new Uri("Target"),
mainRegionName: ConfigurationManager.AppSettings["MainRegion"]));
It might be tempting to specify an application-wide configuration object instead of this type-specific DTO, but that's a trap. Such application-wide configuration object is the configuration equivalent of the Service Locator anti-pattern. It becomes unclear what configuration values a type requires, and makes classes harder to test.
Option 2: Derive from that class
Another option is to derive from that class, just for the purpose of DI configuration. This is especially useful when you can't change the class signature (i.e. when it's a third-party component):
private sealed class DILoginManager : LoginManager
{
DILoginManager(IRegionManager regionManager,
IEventAggregator eventAggregator)
: base(regionManager, eventAggregator,
ConfigurationManager.AppSettings["MainRegion"],
new Uri("Login"),
new Uri("Target"))
{
...
}
}
Define this class close to the composition root of your application. This class becomes an implementation detail of your DI configuration. Registration of your type will now be very simple:
container.RegisterType<ILoginManager, DILoginManager>();
Be very careful though with calls that lazy load configuration values, such as ConfigurationManager.AppSettings["MainRegion"]. This could easily lead to situations where configuration errors are not caught during application startup, which really is preferable.
Option 3: Use a factory delegate
The last option I would like to present is a factory. This will look much like Traveses' answer, but is more type-safe:
var mainRegion = ConfigurationManager.AppSettings["MainRegion"];
container.Register<ILoginManager>(new InjectionFactory(c =>
{
return new LoginManager(
c.Resolve<IRegionManager>(),
c.Resolve<IEventAggregator>(),
ConfigurationManager.AppSettings["MainRegion"],
new Uri("Login"),
new Uri("Target"));
}));
No it's not a bad habit. It is a perfectly valid scenario. It's been few years since I moved on from Unity but from the top of my head with it you have to explicitly point to the constructor you want and enumerate all parameters and for the primitive ones do new ResolvedParameter("your value").
Also I noticed you have a Type parameter there. Be cautious with Unity as it has a... very surprising way of handling those. I have a blogpost detailing that here.

Categories

Resources