Autofac Strategy Pattern Example

CSharp · Console

/Program.cs

using Autofac;
using System;
using System.Reflection;

namespace Samples.Autofac.StrategyPattern
{
    public interface IStrategy { void Do(); }

    public class ConcreteStrategyA : IStrategy { public void Do() { Console.WriteLine("Called ConcreteStrategyA.Do()"); } };
    public class ConcreteStrategyB : IStrategy { public void Do() { Console.WriteLine("Called ConcreteStrategyB.Do()"); } };

    public enum ESomeEnum
    {
        UseStrategyA, UseStrategyB,
    }

    public class Context
    {
        private readonly Func<ESomeEnum, IStrategy> _strategyFactory;

        public Context(Func<ESomeEnum, IStrategy> strategyFactory)
        {
            _strategyFactory = strategyFactory;
        }

        public void DoSomething()
        {
            _strategyFactory(ESomeEnum.UseStrategyB).Do();
            _strategyFactory(ESomeEnum.UseStrategyA).Do();
        }
    }

    public class AutofacExample
    {
        public static void Main()
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<Context>().AsSelf().SingleInstance();
            builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(IStrategy)))
                   .Where(t => typeof(IStrategy).IsAssignableFrom(t))
                   .AsSelf();
            builder.Register<Func<ESomeEnum, IStrategy>>(c =>
            {
                var cc = c.Resolve<IComponentContext>();
                return (someEnum) =>
                {
                    switch (someEnum)
                    {
                        case ESomeEnum.UseStrategyA:
                            return cc.Resolve<ConcreteStrategyA>();
                        case ESomeEnum.UseStrategyB:
                            return cc.Resolve<ConcreteStrategyB>();
                        default:
                            throw new ArgumentException();
                    }
                };
            });

            var container = builder.Build();

            container.Resolve<Context>().DoSomething();
        }
    }
}
;