65.9K
CodeProject 正在变化。 阅读更多。
Home

创建一个小型依赖注入框架

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2013 年 10 月 11 日

CPOL

5分钟阅读

viewsIcon

5742

各位朋友,依赖注入是 ASP.NET 世界中的热门词汇。如今市面上有许多框架,如 Spring.Net、Unity Framework。

各位朋友:

依赖注入是 ASP.NET 世界中的热门词汇。如今市面上有许多框架,如 Spring.Net、Unity Framework、Pico、Avalon 等等。一个典型的 DI 框架包含几个组件。

1. 容器 (Container) : 这是一个映射对象,用于依赖解析。容器是一个容器,在其内部容纳某种抽象。通常,对象管理由正在使用的任何容器负责。

2. 映射指定器 (Mapping Specifier) : 这是一种可配置资源,用于依赖解析。

3. 对象工厂 (Object Factory) : 这通常是一个工厂方法,它使用映射指定器填充容器,并最终将所需的the desired object交付给客户端。

优点 (Benefits) : DI 框架提供了许多优点,以下列出其中一些。

1. 代码量少 (Less code) : 当您使用 DI 框架时,可以节省大量样板代码的编写,其不同组件可用于提供许多常用信息。

2. 单元测试 (Unit Testing) : DI 框架促进了高度的组件解耦,这有助于单元测试。

开发自定义 DI 框架 (Developing a custom DI framework) : 开发这样的框架并不难,一旦完成,它将为我们的应用程序带来一个很棒的设计。因此,在本文中,我们将探讨如何开发这样一个框架。

我们将考虑我们方法论的以下方面。

抽象 (Abstraction) : 抽象是 OOP 的一个重要概念,通常指的是将通用关注点与整体逻辑分离。

无论您处理的是 MVC 应用程序还是 MVP、MVVP、MVVM 应用程序,您都会始终处理称为实体/模型等的对象,它们描述了应用程序中的参与者。

因此,我们的框架将抽象地定义实体的概念。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Abstraction

{

    public abstract class EntityBase

    {

        public abstract bool ValidateEntity();       

    }

}

 

这个基类将以一种通用方式定义实体。

操作抽象 (Abstraction of Operations) : 这指的是实体可以参与的离散操作。在典型的服务应用程序中,我们可以将其泛化为 CRUD 操作。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace Interfaces

{

    public interface IEntityOperations

    {

        EntityBase Create(EntityBase e);

        EntityBase Update(EntityBase e);

        IEnumerable<EntityBase> GetAll();

        EntityBase Delete(EntityBase e);

    }

}

 

整合各部分 (Putting the pieces together) : 定义了上述基本骨架后,我们就可以开始实际使用了。让我们从定义一个实体(Person)开始。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Interfaces;

namespace Entities

{

    public class Person : EntityBase

    {

        public string Name { get; set; }

        public override bool ValidateEntity()

        {

            throw new NotImplementedException();

        }

    }

}

 

现在,让我们也为我们的应用程序定义一个业务层。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using FrameWork;

using Entities;

using Interfaces;

 

namespace BusinessLogic

{

    [AssociatedEntity(typeof(Person))]

    public class PersonBl : IEntityOperations

    {


#region
IEntityOperations Members

 

        public EntityBase Create(EntityBase e)

        {

            return new Person { Name = “Jackie” };

        }

 

        public EntityBase Update(EntityBase e)

        {

            return new Person { Name = “Jackie” };

        }

 

        public IEnumerable<EntityBase> GetAll()

        {

            throw new NotImplementedException();

        }

 

        public EntityBase Delete(EntityBase e)

        {

            throw new NotImplementedException();

        }
#endregion

    }

}

 

这里需要注意的关键点是“AssociatedEntity 属性,它有助于定义实体与其工作类之间的映射。这是该属性的实现。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Interfaces;

 

namespace FrameWork

{

    [AttributeUsage(AttributeTargets.Class)]

    public class AssociatedEntity: Attribute

    {

        Type _t;

        public AssociatedEntity(Type t)

        {
_t = t;

        }

        public Type AssociatedType

        {

            get

            {

                       return _t;

            }

        }

    }

}

工厂方法实现 (The factory method Implementation) : 现在我们已经定义了映射,是时候创建一个工厂类了,它在运行时解析我们的依赖关系以生成所需的the desired object。该方法借助我们的属性在实体/模型及其相应的 BLL 类之间建立关系。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Interfaces;

using System.Reflection;

using System.IO;

using System.Configuration;

 

namespace FrameWork

{

    public static class ServiceContext

    {

        public static IEntityOperations CreateService<T>(T desiredType) where T : EntityBase

        {

            Assembly asm = Assembly.LoadFile(ConfigurationManager.AppSettings["BLLAssembly"]);

            foreach
(Type typ in asm.GetTypes())

            {

foreach (AssociatedEntity attrib in typ.GetCustomAttributes(typeof(AssociatedEntity), false))

{


if (attrib.AssociatedType == typeof(T))

                        return Activator.CreateInstance(typ) as IEntityOperations;
}

            }

            return null;

        }

    }

}

在此方法中,我们主要查找业务逻辑 DLL,以搜索 BLL 类及其关联的实体。此方法也可用于填充 Dictionary 等容器,以存储实体和 BLL 类的映射。

现在我们可以为客户端应用程序使用它了。这是一个使用我们框架的小型控制台应用程序。


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Entities;

using FrameWork;

using Interfaces;

 

namespace ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {           

          Person p = new Person { Name = bruce };         

          IEntityOperations per=ServiceContext.CreateService<Person>(p);

              p.Name=”jackie”;

          p = per.Update(p) as Person;

        }

    }

}


解释与优点


  1. 我们的控制台应用程序(客户端)不了解哪个对象负责处理 Person 实体,它只知道 *IEntityOperations*,并期望 CRUD 操作已定义,这正是创建“*IEntityOperations*”的原因。
  1. 由于客户端和服务器之间没有链接,两者可以同时开发。

3. 即使在实际实现提供之前也可以进行测试。

© . All rights reserved.