-
Notifications
You must be signed in to change notification settings - Fork 9
Application Environment
Applications typically need some environment around them, acting like a root for accessing services, and Kephas applications are no different. In the following we present the built-in services for initializing and accessing this environment in Kephas, so that building applications of all kinds remains flexible while being powerful.
The ambient services are services used at the topmost level in the application. They are first initialized upon application startup, and are accessible through the IAmbientServices service contract. AmbientServices class is the default implementation of this contract. A real world application will have one single instance from which all the application services can be accessed.
- Service contract: IAmbientServices
- Instancing: singleton (shared)
- Mode: single
For classes not participating in composition, as well as for static context, the ambient services are accessible through
AmbientServices.Instancestatic property. However, due to the very nature of static members, accessing this property is strongly discouraged, instead the ambient services should be injected through composition.
The IAmbientServices interface provides the following methods:
-
GetService(serviceType: Type): object: gets the service registered with the provided type. -
RegisterService(serviceType: Type, service: object): registers the service instance with the provided service type. -
RegisterService(serviceType: Type, serviceFactory: Func<object>): registers the service factory with the provided service type. This is useful when the control of the instantiation of ambient services is a requirement. -
IsRegistered(serviceType: Type): boolean: indicates whether a service with the provided type is registered as ambient service.
Note: Invoking
RegisterService()methods multiple times with the same service type will override the previous registrations (last call wins).
Inherited functionality:
- Inherits from the .NET's
IServiceProvider(where theGetServiceis defined). - Is an expando object, so that, at runtime, apart from registering services, additional properties may be attached to it on the fly.
The AmbientServicesBuilder is the class used for initializing the ambient services. If the AmbientServices instance is provided in the constructor, that instance is configured, otherwise the global AmbientServices.Instance is used.
Important: using local ambient services is very handy especially in unit testing, or any other scenario where isolated ambient services are required.
var ambientServicesBuilder = new AmbientServicesBuilder();
await ambientServicesBuilder
.WithNLogManager()
.WithNet45AppEnvironment()
.WithMefCompositionContainerAsync();
var compositionContainer = ambientServicesBuilder.AmbientServices.CompositionContainer;
var appBootstrapper = compositionContainer.GetExport<IAppBootstrapper>();
await appBootstrapper.StartAsync(new AppContext()); var ambientServicesBuilder = new AmbientServicesBuilder(new AmbientServices());
await ambientServicesBuilder
.WithNLogManager()
.WithNet45AppEnvironment()
.WithMefCompositionContainerAsync();
var localAmbientServices = ambientServicesBuilder.AmbientServices;