本篇文章介绍怎么创建自己的模块,并且使用依赖注入方法进行模块间的无缝结合。

我们创建一下自己的一个会员模块,针对不同的系统都可以用。你们可以看看我是怎么做的,或者从中得到启发。

目录

1.开始创建项目

2.新建自己的模块

1)引入类库

2)创建模块类

3)创建实体类与仓储

4)创建service类

5)创建对外用的类(接口)

3.其他模块调用会员模块

1.开始创建项目

首先,我们到ABP官网上下载一个MVC NLayered的解决方案。项目名字叫TestMember

具体怎么下载网上很多资料,这里不一一介绍。

2.新建自己的模块

下载完项目之后,我们新建一个类库,名字叫ClassLibraryMember。用户我们的会员模块。

创建完成之后,如下:

1)引入类库

Install-Package Abp -Version 2.0.2
Install-Package Abp.Zero -Version 2.0.1

当然,你也可以引入自己想要的版本。我们这里用到Zero模块,你也可以不用。

2)创建模块类

首先我们要创建一个模块类,因为ABP是用模块方式的架构来解耦的。模块之间有依赖性,A模块可以依赖于B模块,B模块依赖于A模块。

模块是怎么工作的呢?

我们可以看到,在Web模块里面,有个模块类,叫XXXWebModule,在App_Start文件夹下。在类的上面,有模块的所有依赖:

   [DependsOn(
typeof(AbpWebMvcModule),
typeof(TestMemberDataModule),
typeof(TestMemberApplicationModule),
typeof(TestMemberWebApiModule),
typeof(ClassLibraryMember.ClassLibraryMemberModule))]
public class TestMemberWebModule : AbpModule

ClassLibraryMemberModule模块是作者自己添加进去的,后面再做阐述。

我们看到,首先依赖于AbpWebMvcModule模块,此模块是ABP写的。

然后依赖于TestMemberDataModule模块,此模块是EntityFramework模块的模块类。

然后依赖于TestMemberApplicationModule模块,此模块是Application模块的模块类。

再依赖于TestMemberWebApiModule模块,此模块是WebApi模块的模块类。

最后是自己的模块类(会员模块)ClassLibraryMemberModule。

本次关于模块的调用关系先介绍到这里,有深入兴趣的话,可以看此文章 http://www.cnblogs.com/huaizuo/p/4836853.html

现在,我们创建自己的模块类,叫ClassLibraryMemberModule,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Abp.Dependency;
using Abp.Modules; namespace ClassLibraryMember
{
public class ClassLibraryMemberModule:AbpModule
{ //
// 摘要:
// This method is used to register dependencies for this module.
public override void Initialize()
{
//这行代码的写法基本上是不变的。它的作用是把当前程序集的特定类或接口注册到依赖注入容器中。
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
//
// 摘要:
// This method is called lastly on application startup.
public override void PostInitialize()
{ }
//
// 摘要:
// This is the first event called on application startup. Codes can be placed here
// to run before dependency injection registrations.
public override void PreInitialize()
{ }
//
// 摘要:
// This method is called when the application is being shutdown.
public override void Shutdown()
{ } }
}

可以看到,我们的会员模块,暂时没依赖到其他模块。

这行代码的写法基本上是不变的。它的作用是把当前程序集的特定类或接口注册到依赖注入容器中:

IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

到此我们的模块以及创建成功了。

我们在梳理一下模块的内部调用顺序:

假如模块A依赖于模块B,在项目启动时则运行方法顺序如下:

模块B的PreInitialize –> 模块A的PreInitialize

模块B的Initialize —> 模块A的Initialize

模块B的PostInitialize—> 模块A的PostInitialize

如果项目停止,则:

模块B的Shutdown—> 模块A的Shutdown

3)创建实体类与仓储

我们创建一个实体Member,继承AbpUser,如下:

using System.ComponentModel.DataAnnotations.Schema;
using Abp.Authorization.Users;
using Abp.Domain.Entities;
using Abp.Domain.Entities.Auditing; namespace ClassLibraryMember.Entity
{
[Table("Member")]
public class Member: AbpUser<Member>
{ public string Token { get; set; } public string IdentityType { get; set; } public string Identifier { get; set; } }
}

即使我们创建了实体类,并且写了Table注解,但是怎么才能在新建数据库的时候才能把此表加入到数据库中呢?

所以我们找到EntityFramework中的类XXXDbContext。在此类中,建一个会员类的属性:

public virtual IDbSet<ClassLibraryMember.Entity.Member> Members { get; set; }

最后,我们运行数据库的创建,就能创建Member表了。如下:

4)创建service类

上面我们创建了实体类与数据库,但是怎么实现数据库的CRUD操作呢?

我们写一个会员的service,分别为接口IMemberService,实现类MemberService

在MemberService类中,我们要继承DomainService,此类是用来所有自己创建的domain services用到的。

当我们继承了此类时,有几个好处:

1)自动实例化(依赖注入)

2)继承了AbpServiceBase,此类实现了很多通用的方法,我们都可以用到

为什么继承DomainService会自动实例化呢?因为DomainService继承了ITransientDependency。ABP会扫所有类,如果继承了ITransientDependency,会自动实例化。

接口代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Dependency;
using Abp.Domain.Services; namespace ClassLibraryMember.Core
{
public interface IMemberService
{
void MemberToDo(); }
}

类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.Domain.Uow;
using ClassLibraryMember.Entity; namespace ClassLibraryMember.Core
{
public class MemberService:DomainService,IMemberService
{ private readonly IRepository<Member, long> _memberRepository; public MemberService()
{
} public MemberService(IRepository<Member, long> memberRepository)
{
_memberRepository = memberRepository;
} public void MemberToDo()
{
try
{
Console.WriteLine("MemberService MemberToDo");
_memberRepository.Insert(new Member()
{
Identifier = Guid.NewGuid().ToString(),
IdentityType = "Token",
Token = Guid.NewGuid().ToString().Substring(10, 5),
EmailAddress = "11",
Name = "22",
Surname = "33",
UserName = "44",
Password = "55fddfgfdgd544",
AccessFailedCount = 1,
IsLockoutEnabled = false,
IsPhoneNumberConfirmed = true,
IsTwoFactorEnabled = true,
IsEmailConfirmed = true,
IsActive = true,
IsDeleted = false,
CreationTime = DateTime.Now
});
CurrentUnitOfWork.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
} } }
}

5)创建对外用的类(接口)

上面我们创建了实体,并且实现了逻辑。我们这个会员模块要其他人也可以用,所以我们要创建IMemberClient接口,并且继承ITransientDependency,因为要用到依赖注入:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Dependency; namespace ClassLibraryMember.ServicesClient
{
public interface IMemberClient: ITransientDependency
{ void ToDo(); }
}

在创建它的实现类,MemberClient。此类有一个IMemberService的属性,也是注入的方式。

using ClassLibraryMember.Core;

namespace ClassLibraryMember.ServicesClient
{
public class MemberClient:IMemberClient
{
private IMemberService _memberService; public MemberClient()
{
} public MemberClient(IMemberService memberService)
{
_memberService = memberService;
} public void ToDo()
{
_memberService.MemberToDo();
} }
}

到此,创建自己的类库已经完毕。

那外面怎么用呢,下面开始介绍。

3.其他模块调用会员模块

1)首先,在Web模块里面,Web的模块类里面,添加对会员模块的依赖。

[DependsOn(
typeof(AbpWebMvcModule),
typeof(TestMemberDataModule),
typeof(TestMemberApplicationModule),
typeof(TestMemberWebApiModule),
typeof(ClassLibraryMember.ClassLibraryMemberModule))]
public class TestMemberWebModule : AbpModule

2)然后在EntityFramework仓储里面,添加对Member的实体的创建

public virtual IDbSet<ClassLibraryMember.Entity.Member> Members { get; set; }

3)最后,开始调用。

我们这里从Application模块层里面调用。

首先要实现对IMemberClient的构造器注入,然后调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Dependency;
using Abp.Domain.Repositories;
using ClassLibraryMember.ServicesClient;
using TestMember.Entity; namespace TestMember.Services
{
public class TestAppService: ITestAppService
{ private readonly IMemberClient _iMemberClient; public TestAppService() { } public TestAppService(IMemberClient iMemberClient)
{
_iMemberClient = iMemberClient;
} public void Test1()
{
_iMemberClient.ToDo();
} }
}

到此,调用与测试都完毕,你们可以从GitHub中下载此demo:

https://github.com/cjt321/TestMember2

其他文章:模块化的深入探讨

C# ABP - 创建自己的模块的更多相关文章

  1. 【ABP框架系列学习】模块系统(4)

    0.引言 ABP提供了构建模块和通过组合模块以创建应用程序的基础设施.一个模块可以依赖于另外一个模块.通常,程序集可以认为是模块.如果创建多个程序集的应用程序,建议为每个程序集创建模块定义. 当前,模 ...

  2. ABP创建数据库操作步骤

    1 ABP创建数据库操作步骤 1.1 SimpleTaskSystem.Web项目中的Web.config文件修改数据库配置. <add name="Default" pro ...

  3. OFBiz进阶之HelloWorld(一)创建热部署模块

    创建热部署模块 参考文档 https://cwiki.apache.org/confluence/display/OFBIZ/OFBiz+Tutorial+-+A+Beginners+Developm ...

  4. 从头开始编写一个Orchard网上商店模块(3) - 创建Orchard.Webshop模块项目

    原文地址:http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-par ...

  5. 创建自定义 HTTP 模块

    本主题中描述的自定义 HTTP 模块阐释了 HTTP 模块的基本功能.在响应下面两个事件时调用该模块:BeginRequest 事件和 EndRequest 事件.这使该模块可以在处理页请求之前和之后 ...

  6. npm创建和发布模块

    今天项目需要使用npm去创建一个模块,然后我查询了了npm的使用文档(Working with private modules),然后对其进行了整理. 一.在操作之前,我们首先要将npm装好,并且登录 ...

  7. 创建maven多模块项目(idea工具)

    1.创建父项目模块(new 一个maven空项目模块)不勾选 create from archetype  删除src目录 2.创建子模块 webapp (该模块为web入口模块) 3.创建其他子模块 ...

  8. idea创建Maven多模块项目

    最近几天学习到了创建多模块项目,应为自己使用的是Idea,所以想用idea创建多模块,查阅了相关资料后,自己做一个记录. 一.首先创建一个maven项目 Parent Project,创建xxx-ro ...

  9. IDEA创建多个模块MavenSpringBoot项目

    最近在学习springboot,先从创建项目开始,一般项目都是一个项目下会有多个模块,这里先创建一个最简单的实例,一个项目下有一个springboot模块项目提供web服务,引用另一个java项目(相 ...

随机推荐

  1. java 异步机制与同步机制的区别

    所谓异步输入输出机制,是指在进行输入输出处理时,不必等到输入输出处理完毕才返回.所以异步的同义语是非阻塞(None Blocking). 网上有很多网友用很通俗的比喻  把同步和异步讲解的很透彻 转过 ...

  2. ASP.NET Web API + Elasticsearch 6.x 快速做个全文搜索

    最近想做个全文搜索,设想用 ASP.NET Web API + Elasticsearch 6.x 来实现. 网上搜了下 Elasticsearch 的资料,大部分是讲 linux 平台下如何用 ja ...

  3. 定时任务 Wpf.Quartz.Demo.1

    Quartz 是个开源的作业调度框架. 安装:Install-Package Quartz 官网文档地址:https://www.quartz-scheduler.net/documentation/ ...

  4. 试着用java实现DNS(一)——DatagramSocket, DatagramPacket, Message

    一般来说,自己编写DNS是没有必要的,目前开源的dns服务软件很多,功能也很强大.但是,有时候又是很有必要的,有着诸多好处.比如说,用于企业内网,简化DNS配置,可以根据企业需求添加新的功能,非常灵活 ...

  5. 转---单页面应用下的JS内存管理

    正文从这开始- 内存问题对于后端童鞋而言可能是家常便饭,特别是C++童鞋.我在实习时做过半年的c++游戏客户端开发(也是前端开发哦),也见识了各式各样的内存问题,就说说我的第一个坑,当时做个需求,就是 ...

  6. POJ 2410

    #include <iostream> #include <cmath> #include <string> using namespace std; int gi ...

  7. Solr6.5配置中文分词IKAnalyzer和拼音分词pinyinAnalyzer (二)

    之前在 Solr6.5在Centos6上的安装与配置 (一) 一文中介绍了solr6.5的安装.这篇文章主要介绍创建Solr的Core并配置中文IKAnalyzer分词和拼音检索. 一.创建Core: ...

  8. windows系统numpy的下载与安装教程

    numpy是一款基于python的功能强大的科学计算包.要安装numpy首先你得先安装python.python的安装非常简单,本人安装的是python3.4. 工具/原料 安装好的python程序 ...

  9. Linux机器之间复制文件和目录方式&Linux的scp命令详解

    本文转载于:http://www.cnblogs.com/hitwtx/archive/2011/11/16/2251254.html 整理总结如下: 不同的Linux之间copy文件常用有3种方法: ...

  10. Day.js - JavaScript时间处理库

    Day.js简介 在使用JavaScript处理时间方面,使用的时Moment.js,但是它太重了,有200多k,一般项目中可能也只是用了几个api而已,所以,这里推荐一个轻量的时间库 - Day.j ...