hyankov
hyankov

Reputation: 4120

Dependency Injection and loading application settings once only

I have a custom class - "ApplicationConfigurationManager", which depends on my IDataRepository. Of course, the interface has a concrete implementation, in another assembly. So basically we have:

Business dll
 ApplicationConfigurationManager
 IDataRepository

EfDatabaseAccess dll
 EfDataRepository : IDataRepository

Client.exe
  ref EfDatabaseAccess dll
  ref Business dll

I want the ApplicationConfigurationManager to initialize only once for the entire application runtime life (i.e. Singleton), because it hits the database via IDataRepository. At the same time I want IDataRepository to resolve to EfDataRepository by Unity.

The two don't play well together. How do I keep some class alive, if it depends on Unity to resolve its dependencies.

Upvotes: 0

Views: 515

Answers (2)

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

I assume you want something like Logger.Log("Some text") but still able to setup and properly resolve dependencies with Unity.

You can use Func<IMyInterface> auto-registered by Unity when you register interfaces - using Func version lets you resolve object when you need to use it instead when you initialize the calls.

public static Func<IDbLogger> LoggerGetter {get;set}
public static static Log(string text)
{
    LoggerGetter().Log(text); // will resolve `IDbLogger` at this point
}

....
// during container initialization:
container.Register<IDbLogger>(....);
Logger.LoggerGetter = container.Resolve<Func<IDbLogger>>();

Notes:

  • Func<IMyInterface> created by Unity container is essentially ()=>container.Resolve<IMyInterface>(), so if you want you can just pass such lambda instead. Drawback is that you can't override registration of Func<IMyInterface> if you use lambda directly (rarely needed).
  • this post does not goes into whether using singleton is good/bad idea - make your own calls
  • same technique can be used when lifetime of objects that depend on each other does not match (i.e. Application and Invocation, or HttpRequest and Invocation). To solve that object with longer lifetime should take dependency on Func<...> providing other object and call it when needed.

Upvotes: 0

David L
David L

Reputation: 33815

You should use Lifetime Managers in Unity to control the lifecycle per registered type. In your case, it would look like the following:

container.RegisterType<IDataRepository, DataRepository>();

container.RegisterType<IApplicationConfigurationManager, ApplicationConfigurationManager>
    ("MyMapping", new ContainerControlledLifetimeManager());

Upvotes: 1

Related Questions