OK, maybe here is such question already, but I didn't find it..
The problem
We have big enterprise application with a lot of entry points. App contains part like:
- Server
- Desktop Client
- Some console utilities
- .NET API (separate assembly, with root class called like
MyAppAPI
) - COM API (the same, separate assembly, you can access to API from, for example VBScript, by
Set api = CreateObject("MyApp.MyAppAPI")
- Java API (again, the same)
- Messaging API (separate assembly, used for communicating between layers through messages queues)
We use Unity as DI container in this app. Everything is cool in Server/DesktopClient/Console utilities etc. - there are very concrete entry points, so we just initialize composition root object there, initialize tree of objects/dependencies, and everything works like a charm. Them problem is with our APIs.
#1
How to deal with DI in libraries/frameworks?
From the link above:
The Composition Root is an application infrastructure component.
Only applications should have Composition Roots. Libraries and frameworks shouldn’t.
Yeah, it's cool, but.. I want to use DI in my API, it's huge! How to deal one with other?
#2
We have dependencies, which preferably should be singletons (e.g. some factories, which control lifetime of created objects). But, we can create some instances of API objects, how to share this singleton instances between them? Even more - we can create some instances of .NET API objects and one/some instances of COM API objects in the same domain (if you want, I can explain in the comment when it's possible)..
What I have now
As I said, there is no problem with apps, the problem exists in libraries (APIs). So, what I have now
- I have class
ShellBase
- this class contains static field
_Shells
and public static methodsGet
andRelease
- there is hierarchy between containers (e.g. APIs' containers are inherited from MessagingAPI, Server and DesktopClient containers are inherited from .NET API container etc.)
- when somebody ask for new shell (through
Get
method),ShellBase
checks if there is already such container (or super-container, from subclass), and returns that instance. Or creates new one
I don't like this way, but this is the best what I can imagine right now.
Possible solution
Create something like APIFactory
, which will create our API objects, but it looks.. too complicated for end-users. I don't want to write in user documentation: "Please, create and keep APIFactory instance first, then you can create API instances using this factory". It's ugly. Our users should write just var api = new API()
, and use it.
So, guys, what do you think?