Verify forces lazy initialization of services - c#

Firstly, thank you- I have become a better programmer by being "forced to" by Simple Injector.
Very early in the bootstrap of my program I setup my root container and shortly afterward call container.Verify()
Many of my services take a dependency on (my class) ICurrentUser which has methods to retrieve account secrets and configuration. As would be expected these secret are available only after the user has authenticated, which has not occurred during the bootstrapping and call container.Verify().
example:
private readonly string serviceAccount;
public SomeService(ICurrentUser currentUser) {
serviceAccount = currentUser.GetSecret("SomeServiceAccount");
}
This has caused me to change the above to:
private Lazy<string> serviceAccount;
public SomeService(ICurrentUser currentUser) {
serviceAccount =
new Lazy<string>(() => currentUser.GetSecret("SomeServiceAccount"));
}
and then refer to serviceAccount.Value when it is needed.
This seems a bit awkward and complicates the ctor. Alternatively I could postpone the verify until after the user authenticates but I don't really like that as it postpones what should happen after setting up the ctor.
Is there a way for me to split the verify process into an initial lightweight verification of the service relationships but not execute the constructors until a later step?

Constructors should be free of any logic, other than doing precondition checks and storing incoming dependencies, as explained here by Mark Seemann. This means that you should not make any calls to injected dependencies from inside the constructor, because:
Such invocation might fail, causing the construction of object graphs to become unreliable
During creation of the component, the injected dependency graph graph might, at that point, not yet be fully initialized, which makes the constructor fragile.
Invocation of dependencies can cause constructors to depend on the availability of runtime data (such as your user's secrets), or the availability of external resources (such as a database), making it much harder to verify your container's configuration, which is something you are already experiencing. Component's constructors, however, should not rely on the availability of runtime data, as I explained here.
The solution to this problem simply is to store the incoming ICurrentUser dependency in the SomeService class, and only call its GetSecret method when one of SomeService's methods are invoked.
You might be tempted to make loading of the value lazy, especially to prevent having to load it over and over again, which can happen if GetSecret is called many times throughout the lifetime of SomeService.
You should, however, refrain from implementing caching at that level, because that would complicate SomeService and all other consumers of ICurrentUser. Instead, you should either implement caching inside the ICurrentUser implementation -or- wrap the implementation in a Decorator that adds the caching behavior. Registering decorators in Simple Injector is trivial.

Related

C#: ILogger vs static Log instance

This is more an architectural question:
Do you use ILogger (and pass it in the constructor via DI) or do you prefer a static class Log?
We use ILogger a lot but it really seems to clatter the code especially when it is passed via constructor. If not passed via constructor and just every time created, then I really do not see a benefit if using the interface.
So how do you handle this? I am especially interested in the arguments behind it - not just saying "static" or "interface".
Thx
Using a static instance of anything is a bad idea for different reasons, depending on your use case.
- They are difficult to mock in a unit test so your logger is always writing logs even when they are not needed.
- Lack of mocking also means you cannot write tests to ensure an error log is written in appropriate situations.
- They cannot be replaced at runtime to allow injection of different loggers. This can be important if you are releasing a library for others to use. I define a standard logger interface and log everything to that, then allow clients to inject their own logger as long as it implements my interface.
- If you use the default static Log implementation provided by the vendor, you are locked into their interface meaning you cannot hide or change the surface area of the logger. Changing loggers becomes a MUCH bigger effort if the syntax of the new logger changes.
So that leaves you with some kind of injection. Personally I prefer having all dependencies in the constructor, even if it becomes verbose, because it’s easy to see all dependencies a particular class has. If you are trying to avoid a big constructor you can look into Property Injection. This requires an attribute on a property of the class, but still gives you all the advantages of injecting the dependencies. If you put the injected property on a base class it will be available for all children automatically.
BTW, I’m not a fan of the Ambient Context described above because it’s basically a single purpose DI container, and you must have a concrete reference to multiple ambient service containers. If the easy access of this pattern appeals to you, look into Service Location which is the same idea but more flexible.
If ILogger is really a cross-cutting concern, which is used everywhere and thus just causes to pollute every instance with a new constructor parameter, then what you need is to you use a special way of dependency injection called AmbientContext.
Basically it provides you a singleton Context property, which can be accessed from anywhere in the business scope and contains the "global" dependencies such as logging, time service, etc., whatever you need.
But please note that it doesn't mean you can throw out your ILogger and use a static Log class with a hardcoded implementation. Ambient context is also a way of dependency injection so its dependencies should be resolved.

Dependency injection: single class (WCF service) having multiple dependencies (DB repositories) how to handle?

I've read a book "Dependency injection in .NET" by Mark Seemann and it opened my eyes on many things. But still few question left. Here is one of them:
Let's say we have a WCF service exposing API for working with some database:
public class MyService : IMyService
{
private ITableARepository _reposA;
private ITableARepository _reposB;
//....
public IEnumerable<EntityA> GetAEntities()
{
return _reposA.GetAll().Select(x=>x.ToDTO())
}
public IEnumerable<EntityB> GetBEntities()
{
return _reposB.GetAll().Select(x=>x.ToDTO())
}
//...
}
There may be dozens of repositories service depend on. Some methods use one, some methods another, some methods use few repositories.
And my question is how to correctly organize injection of repository dependencies into service?
Options I see:
Constructor injection. Create a huge constructor with dozens of arguments. Easy for usage, but hard for managing parameters list. Also it's extreemely bad for performance as each unused repository is a waste of resources even if it doesn't use separate DB connection.
Property injection. Optimizes performance, but usage becomes non-obvious. How should creator of the service know which properties to initialize for specific method call? Moreover this creator should be universal for each method call and be located in the composition root. So logic there becomes very complicated and error-prone.
Somewhat non-standard (not described in a book) approach: create a repository factory and depend on it instead of concrete repositories. But the book say factories are very often used incorrectly as a side way to overcome problems that can be resolved much better with proper DI usage. So this approach looks suspicious for me (while achieving both performance and transparency objectives).
Or is there a conceptual problem with this relation 1 to many dependencies?
I assume the answer should differ depending on service instance context mode (probably when it's Single instance, constructor injection is just fine; for PerCall option 3 looks best if to ignore the above warning; for perSession everything depends on the session lifetime: whether it's more close to Single instance or PerCall).
If it really depends on instance context mode, then it becomes hard to change it, because change requires large changes in the code (to move from constructor injection to property injection or to repository factory). But the whole concept of WCF service ensures it is simple to change the instance context mode (and it's not so unlikely that I will need to change it). That makes me even more confused about DI and WCF combination.
Could anyone explain how this case should be resolved correctly?
Create a huge constructor with dozens of arguments
You should not create classes with a huge number of constructor arguments. This is the constructor over-injection code-smell. Having constructors with a huge amount of arguments is an indication that such class does too much: violates the Single Responsibility Principle. This leads to code that is hard to maintain and extend.
Also it's extremely bad for performance as each unused repository is a waste of resources
Have you measured this? The amount of constructor arguments should be mainly irreverent for the performance of the application. This should not cause any noticeable difference in performance. And if it does, it becomes be time to look at the amount of work that your constructors do (since injection constructors should be simple) or its time to switch to a faster DI container if your constructors are simple. Creating a bunch of services classes should normally be blazingly fast.
even if it doesn't use separate DB connection.
The constructors should not open connections in the first place. Again: they should be simple.
Property injection. Optimizes performance
How should creator of the service know which properties to initialize for specific method call
The caller can't reliably determine which dependencies are required, since only constructor arguments are typically required. Requiring properties results in temporal coupling and you lose compile-time support.
Since the caller can't determine which properties are needed, all properties need to be injected and this makes the performance equivalent as with constructor injection, which -as I said- should not be a problem at all.
Somewhat non-standard (not described in a book) approach: create a repository factory and depend on it instead of concrete repositories.
Instead of injecting a repository factory, you could inject a repository provider, a pattern which is better known as the Unit of Work pattern. The unit of work may give access to repositories.
I assume the answer should differ depending on service instance context mode
No, since you should never use the WCF 'Single' mode. In most cases the dependencies you inject into your WCF services are not thread-safe and should not outlive a single request. Injecting them into a singleton WCF service causes Captive Dependencies and this is bad because it leads to all kinds of concurrency bugs.
The core problem here seems that your WCF Service classes are big and violate the Single Responsibily Principle, causing them to hard to create, maintain, and test. Fix this violation by either:
Splitting them up in multiple smaller classes, or
Moving functionality out of them into aggregate services and apply patterns such as the command/handler and query/handler patterns.

Is this an abuse of dependency injection? (when are dependencies not dependencies)

We have a multi-tenant web application in which a many pages operate per-tenant. As a result many of our interfaces look like this
interface ISprocketDeployer
{
void DeploySprocket(int tenantId);
}
It occurred to me that it might be better to simplify these interfaces to be unaware of the tenantId. The pages would also then be unaware of the tenantId, like so
[Inject] // Ninject
public ISprocketDeployer SprocketDeployer { get; set; }
private void _button_OnClick(object sender, EventArgs e)
{
SprocketDeployer.DeploySprocket();
}
The dependency injection framework would then inject the tenant ID as a dependency by looking at the currently authenticated user. Is this a good idea or just an abuse of dependency injection?
It further occurred to me that many implementations also take additional dependencies just for looking up details about the tenant, and that I could reduce the number of dependencies further by just injecting in that detail directly, for example
class SprocketDeployer
{
public SprocketDeployer(ITenantRepository tenantRepository)
{
_tenantRepository = tenantRepository;
}
void DeploySprocket(int tenantId)
{
var tenantName = _tenantRepository.GetTenant(tenantId).Name;
// Do stuff with tenantName
}
}
Would become
class SprocketDeployer
{
public SprocketDeployer(Tenant tenant)
{
_tenant = tenant;
}
void DeploySprocket()
{
var tenantName = _tenant.Name;
// Do stuff with tenantName
}
}
I then realised that I could also inject in other "dependencies", such as details about the currently logged in user in the same way.
At that point I become unsure. While it seemed like a fantastic idea at first I realised that I wasn't sure when to stop adding extra "dependencies". How do I decide what should be a dependency and what should be a parameter?
I would stop short of calling it abuse, but that said:
The general use case of dependency injection (via a container) is to inject pure services that do not directly represent state. One of the immediate problems is informing the container of which instance of your object it should be injecting at run-time. If your SprocketDeployer requires a Tenant, and your system includes many Tenants, how does the container figure out which tenant to supply at runtime?
If you want to avoid passing Tenant around, consider using Thread Local Storage (TLS). However, there will still be some point in the pipeline where the Tenant needs to be added to TLS.
Edit
From your comment:
I solve the problem of figuring out which tenant to supply at runtime
in Ninject by binding the type to a method which examines
HttpContext.Current and using InRequestScope. It works fine, but I've
not seen anything to indicate that this is (or isn't) a recommended
practice.
If I understand you correctly, that sounds like a factory of sorts? If that's the case, I see nothing wrong with it.
A minor nitpick might be: it's nice to be able to not have to be concerned about how your services are scoped. When they are truly stateless services, you can view them as pure swappable components that have no side effects based on container configuration.
As with Phil, I would not call this dependency injection abuse, though it does feel a bit odd.
You have at least a few options. I'll detail a couple that seem the best from the detail you've provided, though these may have been what you were referring to when you said 'I then realised that I could also inject in other "dependencies", such as details about the currently logged in user in the same way.'
Option 1: Abstract tenant identification to a factory
It may make perfect sense to have an abstraction that represents the current tenant. This abstraction is a factory, but I prefer the term "provider" because factory connotes creation whereas a provider may simply retrieve an existing object (Note: I realize Microsoft introduced a provider pattern but that's not what I'm referring to). In this context you're not injecting data, instead you're injecting a service. I'd probably call it ICurrentTenantProvider. The implementation is frequently context specific. Right now, for example, it would come from your HttpContext object. But, you could decide a specific customer needed their own server and then inject an ICurrentTenantProvider that would retrieve it from your web.config file.
Option 2: Hide multitenancy entirely
Unless you ever have to do different things based on the tenant[1], it may be better to hide the multitenancy entirely. In this case you'd inject classes, that I'm going to call providers, that are context aware and the result of whose function calls would be based on the current tenant. For example, you might have an ICssProvider and an IImageProvider. These providers alone would be aware that the application supported multitenancy. They may use another abstraction such as the ICurrentTenantProvider referenced above or may use the HttpContxt directly. Regardless of the implementation, they would return context specific to the tenant.
In both cases, I'd recommend injecting a service instead of data. The service provides an abstraction layer and allows you to inject an implementation that's appropriately context aware.
Making the Decision
How do I decide what should be a dependency and what should be a parameter?
I generally only ever inject services and avoid injecting things like value objects. To decide you might ask yourself some questions:
Would it make sense to register this object type (e.g., int tenantId) in the IoC container?
Is this object/type consistent for the standard lifetime of the application (e.g., instance per http request), or does it change?
Will most objects end up dependent on this particular object/type?
Would this object need to be passed around a lot if made a parameter?
For (1), it doesn't make sense to inject value objects. For (2), if it is consistent, as the tenant would be, it may be better to inject a service that's aware of the tenant. If yes to (3), it may indicate a missing abstraction. If yes to (4) you may again be missing an abstraction.
In the vein of (3) and (4) and depending on the details of the application, I could see ICurrentTenantProvider being injected in a lot of places, which may indicate it's a little low level. At that point the ICssProvider or similar abstractions may be useful.
[1] - If you inject data, like an int, you're forced to query and you may end up in a situation where you'd want to replace conditional with polymorphism.
10/14/15 UPDATE BEGIN
A little over three months later I've had a bit of a change of heart on the specific situation I mentioned running into with this approach.
I had mentioned that for a long time now I've also regularly injected the current "identity" (tenantAccount, user, etc.) wherever it was necessary. But, that I had ran into a situation where I needed the ability to temporarily change that identity for just a portion of the code to be executed (within the same execution thread).
Initially, a clean solution to this situation wasn't obvious to me.
I'm glad to say that in the end I did eventually come up with a viable solution - and it has been happily churning away for some time now.
It will take some time to put together an actual code sample (it's currently implemented in a proprietary system) but in the meantime here is at least a high level conceptual overview.
Note: Name the interfaces, classes, methods, etc. whatever you like - even combine things if that makes sense for you. It's just the overall concepts that are important.
First, we define an IIdentityService, exposing a GetIdenity(). This becomes the de facto dependency for getting the current identity anywhere we need it (repos, services, etc. everything uses this).
The IIdentityService implementation takes a dependency on an IIdentityServiceOrchestrator.
In my system the IIdentityServiceOrchestrator implmentation makes use mutliple IIdentityResolvers (of which only two are actually applicable to this discussion: authenticatedIdentityResolver, and manualIdentityResolver). IIdentityServiceOrchestrator exposes a .Mode property to set the active IIdentityResolver (by default this is set to 'authenticated' in my system).
Now, you could just stop there and inject the IIdentityServiceOrchestrator anywhere you needed to set the identity. But, then you'd be responsible for managing the entire process of setting and rolling back the temporary identity (setting the mode, and also backing up and restoring the identity details if it was already in manual mode, etc.).
So, the next step is to introduce an IIdentityServiceOchestratorTemporaryModeSwitcher. Yes, I know the name is long - Name it what you want. ;) This exposes two methods: SetTemporaryIdentity() and Rollback(). SetTemporaryIdentiy() is overloaded so you can set via mode or manual identity. The implementation takes a dependency on the IIdentityServiceOrchestrator and manages all the details of backing up the current existing identity details, setting the new mode/details, and rolling back the details.
Now, again you could just stop there and inject IIdentityServiceOchestratorTemporaryModeSwitcher anywhere you'd need to set the temporary identity. But, then you'd be forced to .SetTemporaryIdentity() in one place and .Rollback() in another and in practice this can get messy if it's not necessary.
So, now we finally introduce the final pieces of the puzzle: TemporaryIdentityContext and ITemporaryIdentityContextFactory.
TemporaryIdentityContext Implements IDisposable and takes a dependency on both the IIdentityServiceOchestratorTemporaryModeSwitcher and an Identity / Mode set via an overloaded constructor. In the ctor we use the IIdentityServiceOchestratorTemporaryModeSwitcher.SetTemporaryIdentity() to set the temporary identity and on dispose we call into IIdentityServiceOchestratorTemporaryModeSwitcher.Rollback to clean things up.
Now, where we need to set the identity we inject the ITemporaryIdentityContextFactory which exposes a .Create() (again overloaded for identity / mode) and this is how we procure our temporary identity contexts. The returned temporaryIdentityContext object itself isn't really touched it just exists to control the lifetime of the temporary identity.
Example flow:
// Original Identity
Using (_TemporaryIdentityContextFactory.Create(manualIdentity)) {
// Temp Identity Now in place
DoSomeStuff();
}
// Back to original Identity again..
That's pretty much it conceptually; obviously a LOT of the details have been left out.
There's also the matter of IOC lifetime that should be discussed. In its purest form as discussed here, generally each of the componenets (IIdentityService, IIdentityServiceOrchestrator, ITemporaryIdentityContextFactory) could be set to a 'PerRequest' lifetime. However, it could get funky if you happen to be spawing multiple threads from a single request... in which case you'd likely want to go with a 'perthread', etc. lifetime to ensure there was no thread crosstalk on the injections.
Ok, hope that actually helps someone (and didn't come across as completely convoluted, lol). I'll post a code sample that should clear things up further as I have time.
10/14/15 UPDATE END
Just wanted to chime in and say you're not alone in this practice. I've got a couple multi-tenant apps in the wild that inject the tenant information where it's needed in the same manner.
However, I have more recently ran into an issue where doing this has caused me quite a bit of grief.
Just for the sake of example lets say you have the following (very linear) dependency graph:
ISomeService -> IDep2 -> IDep3 -> ISomeRepository -> ITenentInfoProvider
So, ISomeService depends IDep2, which depenends on IDep3... so on and so on until way out in some leaf ITenentInfoProvider is injected.
So, what's the problem? Well, what if in ISomeService you need to act on another tenant than the one you're currently logged in as? How do you get a different set of TenantInfo injected into ISomeRepository?
Well, some IOC containers DO have context-based conditional support (Ninject's "WhenInjectedInto", "WhenAnyAnchestorNamed" bindings for example). So, in simpler cases you could manage something hacky with those.
But what if in ISomeService you need to initiate two operations, each against a different tenant? The above solutions will fail without the introduction of multiple marker interfaces, etc. Changing your code to this extent for the sake of dependency injection just smells bad on multiple levels.
Now, I did come up with a container based solution, but I don't like it.
You can introduce an ITenantInfoResolverStratagy and have an implementation for each "way" of resolving the TenantInfo (AuthenticationBasedTenantInfoResolverStratagy, UserProvidedTenantInfoResolverStratagy, etc.).
Next you introduce a CurrentTenantInfoResolverStratagy (registered with the container as PerRequestLifeTime so it's a singlton for the life of your call, etc.). This can be injected anywhere you need to set the strategy that will be used by downstream clients. So, in our example we inject it into ISomeService, we set the strategy to "UserProvided" (feeding it a TenantId, etc.) and now, down the chain, when ISomeRepository asks ITenentInfoProvider for the TenantInfo, ITenentInfoProvider turns around gets it from an injected CurrentTenantInfoResolverStratagy.
Back in ISomeService, the CurrentTenantInfoResolverStratagy could be changed multiple times as needed.
So, why don't I like this?
To me, this is really just an overly complicated global variable. And in my mind just about all the problems associated globals apply here (unexpected behavior due to it being mutable by anyone at any time, concurrency issues, etc. etc. etc.).
The problem this whole thing sets out to solve (mostly just not having to pass the tenantId / tenantInfo around as a parameter) is probably just not worth the inherent issues that come with it.
So what's a better solution? Well there probably is some elegant thing that I'm just not thinking of (maybe some Chain Of Command implemenation?).
But, really I don't know.
It may not be elegant but passing a TenantId / TenantInfo around as a parameter in any tenant related method calls would definitely avoid this whole debacle.
If anyone else has better ideas please by all means chime in.

Possible Valid Use of a Singleton?

I've got to the point in my design, where I am seriously considering a singleton.
As we all know, the "common" argument is "Never do it! It's terrible!", as if we'd littered our code with a bunch of goto statements.
ServiceStack is a wonderful framework. Myself and my team are sold on it, and we have a complicated web-service based infrastructure to implement. I have been encouraging an asynchronous design, and where possible - using SendAsync on the service-stack clients.
Given we have all these different systems doing different things, it occurred to me I'd like to have a common logger, (A web service in itself actually, with a fall-back to a local text file if the web service is not available - e.g. some demons are stalking the building). Whilst I am a big fan of Dependency Injection, it doesn't seem clean (at least, to me) to be passing a reference to a "use this logger client" to every single asynchronous request.
Given that ServiceStack's failure signature is a Func<TRESPONSE, Exception> (and I have no fault with this), I am not even sure that if the enclosing method that made the call in the first place would have a valid handle.
However, if we had a singleton logger at this point, it doesn't matter where we are in the world, what thread we are on, and what part of a myriad of anonymous functions we are in.
Is this an accepted valid case, or is it a non-argument - down with singletons?
Logging is one of the areas which makes sense to be a singleton, it should never have any side-effects to your code and you will almost always want the same logger to be used globally. The primary thing you should be concerned with when using Singletons is ThreadSafety, which in the case of most Loggers, they're ThreadSafe by default.
ServiceStack's Logging API allows you to both provide a substitutable Logging implementation by configuring it globally on App_Start with:
LogManager.LogFactory = new Log4NetFactory(configureLog4Net:true);
After this point every class now has access to Log4Net's logger defined in the Factory above:
class Any
{
static ILog log = LogManager.GetLogger(typeof(Any));
}
In all Test projects I prefer everything to be logged to the Console, so I just need to set it once with:
LogManager.LogFactory = new ConsoleLogFactory();
By default ServiceStack.Logging, logs to a benign NullLogger which ignores each log entry.
There's only one problem with classic implementation of a singleton -
it is easily accessible, and provokes direct use, which leads to strong coupling,
god objects, etc.
under classic implementation I mean this:
class Singleton
{
public static readonly Singleton Instance = new Singleton();
private Singleton(){}
public void Foo(){}
public void Bar(){}
}
If you use singleton only in terms of an object lifecycle strategy,
and let IoC framework manage this for you, maintaining loose coupling -
there is nothing wrong with having 'just one' instance of a class
for entire lifetime of application, as long as you make sure it is thread-safe.
If you are placing that common logging behind a static facade that application code calls, ask yourself how you would actually unit test that code. This is a problem that Dependency Injection tries to solve, but you are reintroducing it by letting application logic depend on a static class.
There are two other problems you might be having. To question I have for you is: Are you sure you don't log too much, and are you sure you aren't violating the SOLID principles.
I've written an SO answer a year back that discusses those two questions. I advice you to read it.
As always, I prefer to have a factory. This way I can change the implementation in future and maintain the client contract.
You could say that singleton's implmenentation could also change but factories are just more general. For example, the factory could implement arbitrary lifetime policy and change this policy over time or according to your needs. On the other hand, while this is technically possible to implement different lifetime policies for a singleton, what you get then should probably not be considered a "singleton" but rather a "singleton with specific lifetime policy". And this is probably just as bad as it sounds.
Whenever I am to use a singleton, I first consider a factory and most of the times, the factory just wins over singleton. If you really don't like factories, create a static class - a stateless class with static methods only. Chances are, you just don't need an object, just a set of methods.

Pass parameter from a ViewModel to another with IoC

I'm trying to instantiate a SecondViewModel from a MainViewModel injecting in this second one paramaters that are services registered in the IoCContainer and objects from the MainVM.
The code is something of this kind:
class MainViewModel
{
public MainViewModel()
{
}
private string message = "the message";
public string Message { get; set; }
}
class SecondViewModel
{
public SecondViewModel(IService service, string message)
{
}
}
now, i know i can make the IoC Container inject a SecondViewModelFactory (that carries the service instance) into the MainViewModel, so it can create the SVM through it, but what if the implementation of IService is very heavy and i don't want to instantiate it but when i really need it.
And what if i have to instantiate other ViewModels in a similar way? Do I have to create tons of VMFactories and constructor's parameters?
And in case I use a generic ViewModelFactory, it would need to be instantiated passing all the services needed by every ViewModel I have, regardless if they will be created or not.
Do you know any better solution to my case?
In general, the creation of services should not be heavy. Their constructor should do nothing more than storing the incoming dependencies. If it uses some heavy resources in the background, they shouldn't be accessed through the constructor. This keeps the constructor simple (prevents you from having to test it) and allows the object graph to be composed very rapidly.
If there is really no way around this, there are basically two patterns you can apply:
1. Factories
You can inject a factory to delay the creation of a type. Factories are also useful when objects are created that should be controlled explicitly (for instance, instances that should be disposed as soon as possible). There are several ways of creating factories. Some people like to inject Func<T> or Lazy<T> dependencies into their services, but I find this too implicit. I rather inject an ISomeServiceFactory, since I find this more readable. Downside is that you need to define a new interface for this. However, if you find yourself having many factory interfaces, you probably have a problem in your design anyway.
2. Proxies
Instead of creating a factory, you can hide the service behind a proxy. This proxy can implement the same interface as the service and will do the delayed execution for you. This prevents you from letting the application take a dependency on a different interface (an IServiceFactory or Lazy<T> for instance). Especially Lazy<T> leaks details about the creation into the consumer of such a dependency. You can still inject a Lazy<T> into this proxy, if that's convenient. That's not a problem. That proxy would typically be part of your composition root and the rest of your application would still be dependend on your IService and not your Lazy<IService>.
Please be aware that the use of factories, proxies and lazy initiation does complicate the wiring of the container. So don't use if unless you measured that you really need it. They complicate things, because of the indirection, which makes it harder to follow interlectually. And they make it harder to verify your configuration using automated tests. For more information about verifying your container, take a look here and here.
Most IoC Containers supports Lazy dependency to with Lazy<> to avoid creating expensive class immediately.
So in your code, you can make lazy for your expensive IService:
class SecondViewModel
{
public SecondViewModel(Lazy<IService> service, string message)
{
}
}
You can use some popular IoC Containers and see how they support lazy loading: Autofac or NInject

Categories