SoFunction
Updated on 2025-03-07

C# typical factory implementation example

Factory interface definition

Copy the codeThe code is as follows:

/// <summary>
/// Factory interface definition
    /// </summary>
    /// <remarks>
    ///     TTarget : abstract product type
    ///     TSource:  concrete product type
    /// </remarks>
    public interface IFactory
    {
        #region config and register type mapping

        /// <summary>
/// If you need to load the mapping relationship defined in the configuration file at the same time, you can define independent configuration types according to the principles of SRP.
/// The two interfaces are called by this configuration type to load configuration information for Factory
        /// </summary>

        IFactory RegisterType<TTarget, TSource>();  // fluent interface
        IFactory RegisterType<TTarget, TSource>(string name);   // fluent interface

        #endregion

        #region factory method

        TTarget Create<TTarget>();
        TTarget Create<TTarget>(string name);

        #endregion
    }

Registration Class

Copy the codeThe code is as follows:

public sealed class TypeRegistry
    {
        readonly string DefaultNmae = ().ToString();
        IDictionary<Type, IDictionary<string, Type>> registry = new Dictionary<Type, IDictionary<string, Type>>();
        public void RegisterType(Type targetType,Type sourceType)
        {
            RegisterType(targetType, sourceType, DefaultNmae);
        }
        public void RegisterType(Type targetType, Type sourceType,string name)
        {
            if (targetType == null) throw new ArgumentNullException("targetType");
            if (sourceType == null) throw new ArgumentNullException("sourceType");
            if ((name)) throw new ArgumentNullException("name");
            IDictionary<string, Type> subDictionary;

            if (!(targetType, out subDictionary))
            {
                subDictionary = new Dictionary<string, Type>();
                (name, sourceType);
                (targetType, subDictionary);
            }
            else
            {
                if ((name))
                    throw new DuplicateKeyException(name);
                (name, sourceType);
            }
        }
        public Type this[Type targetType, string name]
        {
            get
            {
                if (targetType == null) throw new ArgumentNullException("targetType");
                if ((name)) throw new ArgumentNullException("name");
                if (() == 0)
                    return null;

                return (registry
                    .Where(x => == targetType)).FirstOrDefault().Value
                    .Where(x => (name, ))
                        .FirstOrDefault().Value;
            }
        }

        public Type this[Type targetType]
        {
            get { return this[targetType, DefaultNmae]; }
        }

    }

Factory

Copy the codeThe code is as follows:

public class Factory : IFactory
    {
        protected TypeRegistry registry = new TypeRegistry();

        #region IFactory Members

        public IFactory RegisterType<TTarget, TSource>()
        {
            (typeof(TTarget), typeof(TSource));
            return this;
        }

        public IFactory RegisterType<TTarget, TSource>(string name)
        {
            (typeof(TTarget), typeof(TSource), name);
            return this;
        }

        public TTarget Create<TTarget>()
        {
            return (TTarget)(registry[typeof(TTarget)]);
        }

        public TTarget Create<TTarget>(string name)
        {
            return (TTarget)(registry[typeof(TTarget), name]);
        }

        #endregion
    }

Call

Copy the codeThe code is as follows:

[TestMethod]
        public void CreateInstance()
        {
            var factory = new Factory()
                .RegisterType<IFruit, Apple>()
                .RegisterType<IFruit, Orange>("o")
                .RegisterType<IVehicle, Bicycle>()
                .RegisterType<IVehicle, Bicycle>("a")
                .RegisterType<IVehicle, Train>("b")
                .RegisterType<IVehicle, Car>("c");

            (<IFruit>(), typeof(Apple));
            (<IFruit>("o"), typeof (Orange));

            (<IVehicle>(), typeof(Bicycle));
            (<IVehicle>("a"), typeof(Bicycle));
            (<IVehicle>("b"), typeof(Train));
            (<IVehicle>("c"), typeof(Car));
        }

In fact, the essence lies in the registration class's assembly-like function, which is encapsulated through dictionary, and then compared through generics, or a new instantiation is achieved through the configuration file.

Pay attention to coherent interfaces, generics, etc.