1

In Unity, I can register a named type like this

using Microsoft.Practices.Unity;
var container = new UnityContainer();
container.RegisterType<IOutputService, ConsoleOutputService>("Console");
container.RegisterType<IOutputService, MessageBoxOutputService>("MessageBox");
container.RegisterType<ICalculatorReplLoop, CalculatorReplLoop>();
ICalculatorReplLoop loop = container.Resolve<ICalculatorReplLoop>();

and auto resolve it using attribute like this

public class CalculatorReplLoop : ICalculatorReplLoop
{
    public CalculatorReplLoop() {}

    [Dependency("MessageBox")]
    public IOutputService OutputService { get; set; }
}

I know how to register Named Service in Autofac

using Autofac;
using Autofac.Core;
var builder = new ContainerBuilder();
builder.RegisterType<ConsoleOutputService>().Named<IOutputService>("Console");
builder.RegisterType<MessageBoxOutputService>().Named<IOutputService>("MessageBox");
builder.RegisterType<CalculatorReplLoop>().As<ICalculatorReplLoop>().SingleInstance();
IContainer container = builder.Build();
ICalculatorReplLoop loop = container.Resolve<ICalculatorReplLoop>();

but how to resolve it inside CalculatorReplLoop class ?

Wesley Lomax
  • 2,067
  • 2
  • 20
  • 34
Jeson Martajaya
  • 6,996
  • 7
  • 54
  • 56

1 Answers1

1

Look at this Sample code and this is one of the ways of auto resolve the using autofac when you share a contract with two implementations.

using System;
using Autofac;
using Autofac.Features.Indexed;

namespace AutoFac
{      
    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<OnlineState>().Keyed<IDeviceState>("online");
            builder.RegisterType<OfflineState>().Keyed<IDeviceState>("offline");
            builder.RegisterType<Modem>().AsImplementedInterfaces();
        
           var container = builder.Build();
    
            var r = container.Resolve<IModem>();
            r.print(); 
        }
    }

    public interface IDeviceState
    {
        string Get();
    }

    public class OnlineState : IDeviceState
    {
        public string Get()
        {
            return "OnlineState";
        }
    }

    public class OfflineState : IDeviceState
    {
        public string Get()
        {
            return "OfflineState";
        }
    }

    public class Modem  : IModem
    {
         readonly IIndex<string, IDeviceState> _states;
         private readonly IDeviceState _deviceState;
         public Modem(IIndex<string, IDeviceState> states)
         {
             _states = states;
             _deviceState = _states["online"];
            //_deviceState = _states["offline"];
         }

         public void print()
         {
             Console.WriteLine(_deviceState.Get());
         }
    }

    public interface IModem
    {
        void print();
    }
}
Cellcon
  • 1,245
  • 2
  • 11
  • 27
Prashant
  • 460
  • 3
  • 12
  • Using IIndex works. I mark your posting as the answer. However, is there a way to have it without using AsImplementedInterface ? – Jeson Martajaya Oct 23 '15 at 14:07
  • why not AsImplementedInterface ? what is the problem you see with that. – Prashant Oct 23 '15 at 14:08
  • 1
    you can use this too... if you want to.. builder.RegisterType().As().SingleInstance(); – Prashant Oct 23 '15 at 14:09
  • Awesome, IIndex does not required AsImplementedInterface(). I just upvoted this answer. What makes you choose AsImplementedInterface in the first place ? I am new to Autofac. – Jeson Martajaya Oct 23 '15 at 14:34
  • 1
    when you are implementing multiple interfaces this is easy way of doing it. I used AsImplementedInterface() out of the habit but its same as builder.RegisterType().As() if you have just one interface to implement. – Prashant Oct 23 '15 at 15:14