Unity 5.x dependency injection container for .NET Framework 4.7. Container setup, lifetime managers, MVC 5 + Web API 2 integration, registration patterns. NOT Microsoft.Extensions.DependencyInjection.
CRITICAL: This is the Unity DI container (Unity.Container), NOT Microsoft.Extensions.DependencyInjection (ASP.NET Core). Different API, different lifetime models, different registration patterns.
using Unity;
using Unity.Lifetime;
IUnityContainer container = new UnityContainer();
// Interface → Implementation
container.RegisterType<IService, MyService>();
// With lifetime
container.RegisterType<ILogger, FileLogger>(new ContainerControlledLifetimeManager());
// Existing instance
container.RegisterInstance<IAppConfig>(new AppConfig { ConnStr = "..." });
// Resolve
IService service = container.Resolve<IService>();
Constructor selection: Unity picks the constructor with the longest parameter list by default. Override with InjectionConstructor:
container.RegisterType<ILogger, MockLogger>(
new ContainerControlledLifetimeManager(),
new InjectionConstructor() // force parameterless constructor
);
| Manager | Behavior | Use For |
|---------|----------|---------|
| TransientLifetimeManager | Default. New instance every Resolve() | Stateless services |
| ContainerControlledLifetimeManager | Singleton within container + children | App-wide singletons |
| SingletonLifetimeManager | Global singleton across entire container tree | Truly global state |
| HierarchicalLifetimeManager | Per-scope singleton (child gets its own) | Per-request in ASP.NET |
| PerResolveLifetimeManager | Singleton within one Resolve() call graph | Shared dependency in one resolution |
| ContainerControlledTransientManager | Transient but container tracks + disposes | Disposable transients |
| ExternallyControlledLifetimeManager | Weak reference only | Externally managed objects |
| PerThreadLifetimeManager | One per thread | Thread-local state |
// HierarchicalLifetimeManager + child containers = per-request scope
container.RegisterType<IDbContext, MyContext>(new HierarchicalLifetimeManager());
The MVC/Web API integration creates a child container per request. HierarchicalLifetimeManager gives each child its own instance.
Package: Unity.Mvc (v5.11.1)
// App_Start/UnityConfig.cs
using Unity;
using Unity.Mvc;
using System.Web.Mvc;
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IProductRepository, ProductRepository>();
container.RegisterType<IOrderService, OrderService>(
new HierarchicalLifetimeManager());
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
Package: Unity.AspNet.WebApi (v5.11.2)
// App_Start/UnityWebApiActivator.cs
using Unity;
using Unity.AspNet.WebApi;
using System.Web.Http;
public static class UnityWebApiActivator
{
public static void Start()
{
var container = new UnityContainer();
container.RegisterType<IProductService, ProductService>();
container.RegisterType<IUserRepository, UserRepository>(
new HierarchicalLifetimeManager());
GlobalConfiguration.Configuration.DependencyResolver =
new UnityDependencyResolver(container);
}
}
Share the same UnityContainer but set two separate resolvers:
var container = new UnityContainer();
// ... registrations ...
// MVC resolver
System.Web.Mvc.DependencyResolver.SetResolver(new Unity.Mvc.UnityDependencyResolver(container));
// Web API resolver (different class, different namespace)
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.AspNet.WebApi.UnityDependencyResolver(container);
public class OrderService : IOrderService
{
private readonly IRepository _repo;
private readonly ILogger _logger;
// Unity resolves both automatically
public OrderService(IRepository repo, ILogger logger)
{
_repo = repo;
_logger = logger;
}
}
using Unity;
public class OrderService : IOrderService
{
[Dependency]
public ILogger Logger { get; set; }
[Dependency("special")] // Named dependency
public ICache Cache { get; set; }
}
// Or via registration
container.RegisterType<IOrderService, OrderService>(
new InjectionProperty("Logger"));
container.RegisterType<INotifier, EmailNotifier>("email");
container.RegisterType<INotifier, SmsNotifier>("sms");
// Resolve specific
INotifier email = container.Resolve<INotifier>("email");
// Resolve ALL named (does NOT include default unnamed)
IEnumerable<INotifier> all = container.ResolveAll<INotifier>();
// Inject specific named dependency
container.RegisterType<AlertService>(
new InjectionConstructor(new ResolvedParameter<INotifier>("sms")));
using Unity.RegistrationByConvention;
container.RegisterTypes(
AllClasses.FromLoadedAssemblies()
.Where(t => t.Namespace?.StartsWith("MyApp.Services") == true),
WithMappings.FromMatchingInterface, // IFoo → Foo
WithName.Default,
WithLifetime.Transient
);
| Pitfall | Problem | Solution |
|---------|---------|----------|
| Singleton holds per-request dependency | Captive dependency — scoped object lives forever | Use same or longer lifetime for dependencies |
| IDisposable with TransientLifetimeManager | Container doesn't track/dispose transients | Use ContainerControlledTransientManager or dispose manually |
| Forgetting to dispose child containers | Scoped singletons leak | Ensure MVC/WebAPI integration disposes per-request containers |
| Sharing InjectionConstructor instances | Runtime errors | Each RegisterType needs its own InjectionConstructor |
| ContainerControlledLifetimeManager + IDisposable | Object never disposed until container dies | Call container.Dispose() on app shutdown |
| v5.2.1 singleton sharing change | Two interfaces mapping to same impl no longer share instance | Register impl separately, then map both interfaces |
// Before 5.2.1: these share one MockLogger instance
container.RegisterType<ILogger, MockLogger>(new ContainerControlledLifetimeManager());
container.RegisterType<IDebugger, MockLogger>(new ContainerControlledLifetimeManager());
// After 5.2.1: these create SEPARATE instances. To share:
container.RegisterType<MockLogger>(new ContainerControlledLifetimeManager());
container.RegisterType<ILogger, MockLogger>();
container.RegisterType<IDebugger, MockLogger>();
HierarchicalLifetimeManager used for per-request services (DbContext, UnitOfWork)ContainerControlledLifetimeManager used for true singletons onlycontainer.Dispose() called in Application_End[Dependency] property injectionInjectionConstructor instances across registrationsSearch for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer