Appearance
Using the Container Model
The queryable Container.Model
is a power facility to look into your Lamar Container
and even to eject previously built services from the Container. The Container.Model
represents a static view of what a Container
already has, and does not account for policies that may allow Lamar to validly discover types that it may encounter later at runtime.
Querying for Service Types
The WhatDoIHave() mechanism works by just iterating over the Container.Model.ServiceTypes
collection as shown below:
cs
container.Model.PluginTypes.Where(x => x.PluginType.Assembly == Assembly.GetExecutingAssembly())
.Each(pluginType => Debug.WriteLine(pluginType.PluginType));
Working with a Service Type
The IServiceFamilyConfiguration
interface allows you to query and manipulate all the configured Instance's for a given service type.
See the entire IServiceFamilyConfiguration interface here.
Finding the Default for a Service Type
To simply find out what the default concrete type would be for a requested service type, use one of these two methods:
cs
// Finding the concrete type of the default
// IDevice service
container.Model.DefaultTypeFor<IDevice>()
.ShouldBe(typeof(DefaultDevice));
// Find the configuration model for the default
// IDevice service
container.Model.For<IDevice>().Default
.ReturnedType.ShouldBe(typeof(DefaultDevice));
Finding an Instance by Type and Name
Use this syntax to find information about an Instance in a given service type and name:
cs
var redRule = container.Model.Find<Rule>("Red");
All Instances for a Service Type
This sample shows how you could iterate or query over all the registered instances for a single service type:
cs
container.Model.For<Rule>().Instances.Each(i =>
{
Debug.WriteLine(i.Instance.Description);
});
Testing for Registrations
To troubleshoot or automate testing of Container configuration, you can use code like the sample below to test for the presence of expected configurations:
cs
// Is there a default instance for IDevice?
container.Model.HasDefaultImplementationFor<IDevice>().ShouldBeTrue();
// Are there any configured instances for IDevice?
container.Model.HasImplementationsFor<IDevice>().ShouldBeTrue();
Finding all Possible Implementors of an Interface
Forget about what types are registered for whatever service types and consider this, what if you have an interface called IStartable
that just denotes objects that will need to be activated after the container is bootstrapped?
If our interface is this below:
cs
public interface IStartable : IDisposable
{
void Start();
}
cs
public interface IStartable
{
bool WasStarted { get; }
void Start();
}
cs
public interface IStartable
{
bool WasStarted { get; }
void Start();
}
We could walk through the entire Lamar model and find every registered instance that implements this interface, create each, and call the Start()
method like in this code below:
cs
var allStartables = container.Model.GetAllPossible<IStartable>()
.ToArray();
foreach (var startable in allStartables) startable.Start();
cs
var allStartables = container.Model.GetAllPossible<IStartable>();
allStartables.ToArray()
.Each(x => x.Start());
I've also used this mechanism in automated testing to reach out to all singleton services that may have state to clear out their data between tests.