Unity
Dependency Injection
Constructor `Parameters`
Resolve Method
C#

Can I pass constructor parameters to Unity's Resolve method?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Yes, Unity can accept runtime constructor values during resolution, but not by giving Resolve a normal positional argument list. The usual approach is to pass override objects such as ParameterOverride or redesign the registration so the container stays responsible for object construction.

Why Resolve Does Not Look Like new

Dependency injection containers try to centralize object creation rules. If Resolve accepted arbitrary constructor arguments the same way new does, composition logic would spread across the codebase and become harder to reason about.

That is why Unity expects you to register types first and then optionally supply explicit override instructions when one constructor argument must be chosen at runtime.

Use ParameterOverride for Runtime Scalar Values

The most common case is a constructor that takes both injected services and one runtime value such as a connection string, tenant id, or file path. Unity supports that with ParameterOverride.

csharp
1using System;
2using Unity;
3using Unity.Resolution;
4
5public interface ILogger
6{
7    void Log(string message);
8}
9
10public class ConsoleLogger : ILogger
11{
12    public void Log(string message) => Console.WriteLine(message);
13}
14
15public class ReportService
16{
17    private readonly string _region;
18    private readonly ILogger _logger;
19
20    public ReportService(string region, ILogger logger)
21    {
22        _region = region;
23        _logger = logger;
24    }
25
26    public void Run()
27    {
28        _logger.Log($"Running report for {_region}");
29    }
30}
31
32public static class Program
33{
34    public static void Main()
35    {
36        IUnityContainer container = new UnityContainer();
37        container.RegisterType<ILogger, ConsoleLogger>();
38        container.RegisterType<ReportService>();
39
40        ReportService service = container.Resolve<ReportService>(
41            new ParameterOverride("region", "ca-east"));
42
43        service.Run();
44    }
45}

Here Unity still resolves ILogger from the container, but the region constructor argument is supplied at the call site.

The parameter name matters. ParameterOverride("region", "ca-east") matches the constructor parameter by name, not just by type.

Use DependencyOverride for a Specific Dependency Instance

Sometimes the runtime value is not a primitive or string. Instead, you want to replace one dependency with a specific instance for a particular resolution. That is what DependencyOverride is for.

csharp
1var specialLogger = new ConsoleLogger();
2
3ReportService service = container.Resolve<ReportService>(
4    new ParameterOverride("region", "eu-west"),
5    new DependencyOverride<ILogger>(specialLogger));

This is useful in tests, temporary workflows, or background jobs where one dependency differs from the normal application registration.

Factory Registrations Are Often Cleaner

If you find yourself passing overrides repeatedly, a factory is usually a better design. The factory keeps the container wiring in one place and makes the runtime input explicit.

csharp
1using System;
2using Unity;
3using Unity.Resolution;
4
5public static class FactoryExample
6{
7    public static void Main()
8    {
9        IUnityContainer container = new UnityContainer();
10        container.RegisterType<ILogger, ConsoleLogger>();
11        container.RegisterType<ReportService>();
12
13        container.RegisterFactory<Func<string, ReportService>>(c =>
14            region => c.Resolve<ReportService>(
15                new ParameterOverride("region", region)));
16
17        var factory = container.Resolve<Func<string, ReportService>>();
18
19        ReportService first = factory("us-east");
20        ReportService second = factory("ap-south");
21
22        first.Run();
23        second.Run();
24    }
25}

This approach usually reads better than scattering ParameterOverride calls all over the application.

Another Option: Register the Constructor Rule

If the value is not truly dynamic and should always be the same for a given registration, do not pass it at resolve time. Register it as part of the container setup instead.

csharp
1using Unity.Injection;
2
3container.RegisterType<ReportService>(
4    new InjectionConstructor("default-region", new ResolvedParameter<ILogger>())
5);

This is appropriate when the parameter is configuration, not per-request data.

Common Pitfalls

  • Expecting Resolve to accept normal constructor arguments by position.
  • Misspelling the constructor parameter name in ParameterOverride.
  • Passing many overrides and effectively rebuilding the object graph outside the container.
  • Using resolve-time overrides for stable configuration that belongs in registration.
  • Replacing dependencies casually without thinking about lifetime and disposal behavior.

Summary

  • Unity does support runtime constructor values, but through override objects rather than a plain argument list.
  • Use ParameterOverride for scalar constructor inputs such as strings and ids.
  • Use DependencyOverride when one resolved dependency must be replaced for a single call.
  • Prefer a factory registration if the same override pattern happens repeatedly.
  • Keep stable configuration in container registrations, not at every resolve call.

Course illustration
Course illustration

All Rights Reserved.