仓储设计模式和容器

  最近研习了一下公司的框架,挺简单的其实就是一个容器和一个仓储,所有的service对象都是放在容器中,而且容器中只会保存一份该对象,也有解耦的作用。下面是一个精简的框架。

    首先定义一个容器的接口.

namespace mycontainer.factory
{
    public interface IContainer
    {
        /// <summary>
        /// 往容器中注册对象
        /// </summary>
        /// <typeparam name="TRepository"></typeparam>
        /// <param name="factory"></param>
        void Register<TRepository>(Func<TRepository> factory);
        /// <summary>
        ///  从容器中获取对象
        /// </summary>
        /// <typeparam name="TRepository"></typeparam>
        /// <returns></returns>
        TRepository Resolve<TRepository>();
    }
}

定义一个容器实现该接口

namespace mycontainer.factory
{
    internal class Container : IContainer
    {
        private readonly ConcurrentDictionary<Type, object> _factories;

        public Container()
        {
            _factories=new ConcurrentDictionary<Type, object>();
        }

        public void Register<TRepository>(Func<TRepository> factory)
        {
            Type key = typeof (TRepository);
            _factories[key] = factory;
        }

        public TRepository Resolve<TRepository>()
        {
            object factory;
            if(_factories.TryGetValue(typeof(TRepository),out factory))
            {
                return ((Func<TRepository>) factory)();
            }
            throw new ArgumentException("************没有注册该对象***********");
        }
    }
}

ConcurrentDictionary字典是线程安全的,在某些特定的时候性能也比较好,所以我们用这个对象作为service对象容器

namespace mycontainer.factory
{
    public class ContainerLocator
    {
        private static  ContainerLocator _instance=new ContainerLocator();
        /// <summary>
        /// 容器的一个接口
        /// </summary>
        private IContainer _container;

        public static IContainer Container
        {
            get { return _instance._container; }
        }
        /// <summary>
        /// 容器加载的一个实例对象
        /// </summary>
        public static ContainerLocator Instance
        {
            get { return _instance; }
        }

        private ContainerLocator()
        {
            _container=new Container();
            RegisterDefaults(_container);
        }
        /// <summary>
        /// 进行对象注册
        /// </summary>
        /// <param name="_container"></param>
        private void RegisterDefaults(IContainer _container)
        {
           _container.Register<IEnglish>(()=>new English());
        }
    }
}

接下来是仓储层,仓储层里面这样是接口和一些接口的代码实现,一定要记住哪层做哪层的事,千万不能弄串了,不然后期维护会很费劲

一个简单的接口

namespace mycontainer.Repositories
{
   public interface IBase
   {
       string ShowHi();
    }
}

这个是基接口,所有接口的通用的方法定义就写在这个里面,

下面是各个数据访问层对象的接口,这里就给个简单的空接口和接口的实现

namespace mycontainer.Repositories
{
    public interface IEnglish:IBase
    {   
    }
}
namespace mycontainer.Repositories
{
    public class English:IEnglish
    {
        public string ShowHi()
        {
            return "Hello !!!";
        }
    }
}

嗯,仓储层就写好了,这里框架简单,可以认为就是一个数据访问层,接下来就是最后的服务层,也叫业务逻辑层

namespace mycontainer.service
{
    public class HelloService
    {
        private readonly IEnglish english;

        public HelloService()
        {
            english = ContainerLocator.Container.Resolve<IEnglish>();
        }

        public string SayHi()
        {
            return english.ShowHi();
        }
    }
}

这样一个简单的框架就完成了,虽然仓储层写的简单,如果以后系统复杂,仓储层可以就行很好的扩展

namespace service
{
    class Program
    {
        static void Main(string[] args)
        {
            HelloService service = new HelloService();
            string str = service.SayHi();
            Console.WriteLine(str);
            Console.ReadKey();
        }
    }
}

下载 http://files.cnblogs.com/dongqinglove/MyContainer.rar

原文地址:https://www.cnblogs.com/dongqinglove/p/3815249.html