Skip to content

Instantly share code, notes, and snippets.

@brandonmartinez
Created January 9, 2014 15:39
Show Gist options
  • Save brandonmartinez/8336110 to your computer and use it in GitHub Desktop.
Save brandonmartinez/8336110 to your computer and use it in GitHub Desktop.
A sample structure map configuration. Requires the StructureMap nuget package (obviously). Can paste into a console app to run and test the demo.
using System;
using System.Collections.Generic;
using System.Linq;
using StructureMap;
using StructureMap.Configuration.DSL;
namespace StructureMapExample
{
/// <summary>
/// A registry; I configure these one per "area" of my application. If it's a
/// small application, you may have only one registry. This is still the preferred
/// approach, apposed to configuring directly in the container
/// </summary>
internal class SampleRegistryOne : Registry
{
#region Constructors
public SampleRegistryOne()
{
// Setup a default instance (this auto-adds the instance); this is basically for autowiring, but is
// the most common syntax when you're doing the repository pattern in my experience
For<IRepository>().Use<SampleRepository>().Ctor<string>().Is("Repository One - The Default");
// Add additional instances
For<IRepository>().Add<SampleRepository>().Ctor<string>().Is("Repository Two");
For<IRepository>().Add<SampleRepository>().Ctor<string>().Is("Repository Three");
// Sometimes you run into issues where it just can't best-guess the ctor properly,
// in those cases, specify the param name
For<IRepository>().Add<SampleRepository>().Ctor<string>("name").Is("Repository Four");
// Create a named instance
For<IRepository>().Add<SampleRepository>().Ctor<string>("name").Is("Repository Five").Named("SpecialInstance");
// Setup our service. Notice that we don't have to specify constructor arguments
// or anything here. This is because a.) we have one constructor, b.) the constructor
// has no primitive arguments, and c.) all of the dependencies for it have
// been previously wired up
For<IService>().Use<SampleService>();
// Add another instance, but this time we have multiple constructor parameters _and_ a primitive.
// We'll have to manually wire
For<IService>()
.Add<SampleMultiConstructorService>()
.Ctor<IRepository>()
.Is(ctx => ctx.GetInstance<IRepository>("SpecialInstance"))
.Ctor<string>("someValue")
.Is("Value");
}
#endregion
}
internal static class MyProjectContainer
{
#region Properties
public static IContainer Container { get; set; }
#endregion
#region Constructors
static MyProjectContainer()
{
Container = new Container();
}
#endregion
}
internal interface IRepository
{
#region Properties
string Name { get; }
#endregion
}
internal class SampleRepository : IRepository
{
#region Constructors
public SampleRepository(string name)
{
Name = name;
}
#endregion
#region IRepository Members
public string Name { get; private set; }
#endregion
}
internal interface IService
{
#region Properties
string RepositoryNames { get; }
#endregion
}
internal class SampleService : IService
{
#region Fields
protected readonly IEnumerable<IRepository> Repositories;
#endregion
#region Constructors
public SampleService(IEnumerable<IRepository> repositories)
{
Repositories = repositories;
}
#endregion
#region IService Members
public string RepositoryNames
{
get
{
return "Repositories: " + string.Join(", ", Repositories.Select(x => x.Name));
}
}
#endregion
}
internal class SampleMultiConstructorService : SampleService
{
public string SomeValue { get; set; }
#region Constructors
public SampleMultiConstructorService(IRepository repository, string someValue) : this(new[]
{
repository
})
{
SomeValue = someValue;
}
public SampleMultiConstructorService(IEnumerable<IRepository> repositories) : base(repositories) { }
#endregion
}
internal class Program
{
#region Static Methods
private static void Main(string[] args)
{
var container = configureContainer();
#if DEBUG
container.AssertConfigurationIsValid();
//Console.WriteLine(container.WhatDoIHave());
#endif
Console.WriteLine("Get all configured instances of IService");
var services = container.GetAllInstances<IService>();
foreach(var service in services)
{
Console.WriteLine("Service Configured. " + service.RepositoryNames);
if(service is SampleMultiConstructorService)
{
Console.WriteLine("An additional value is present: " + (service as SampleMultiConstructorService).SomeValue);
}
}
Console.WriteLine("Grabbing something out of the container.");
// If you were putting together your own factory, this would be a good way to grab what
// was requested of your factory. I'd recommend still assembling your own factory, then
// you don't have a hard depedency on StructureMap and could swap out your IoC container
// if you choose to
var instance = container.GetInstance<IService>();
Console.WriteLine("Instance Type: " + instance.GetType().Name + ". Repositories: " + instance.RepositoryNames);
Console.ReadKey();
}
private static IContainer configureContainer()
{
var container = MyProjectContainer.Container;
container.Configure((c) =>
{
// Add registries here
// ORDER MATTERS
c.AddRegistry<SampleRegistryOne>();
});
return container;
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment