• C# ABP


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

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

    目录

    1.开始创建项目

    2.新建自己的模块

         1)引入类库

         2)创建模块类

         3)创建实体类与仓储

         4)创建service类

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

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

        

        

    1.开始创建项目

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

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

    2.新建自己的模块

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

    创建完成之后,如下:

    image

    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表了。如下:

    image

    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

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

  • 相关阅读:
    查询BLOB字段的长度
    java中使用公钥加密私钥解密原理实现license控制
    Eclipse调试Bug的七种常用技巧
    mysql视图
    动态缓存技术之CSI,SSI,ESI
    取得图片原来的大小
    fieldset也是表单元素
    isInt
    取得浏览器的文档类型
    option的value、text与label
  • 原文地址:https://www.cnblogs.com/alunchen/p/7090378.html
Copyright © 2020-2023  润新知