.Net Core Blazor Server 页面路由

startup.cs中做如下配置

services.AddMvc().AddRazorPagesOptions(options =>
{
      options.Conventions.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute());
      options.Conventions.AddPageRoute("/login/login", "/api/login/{id?}");
      options.Conventions.AddPageRoute("/videosms/tpl/edit", "/videosms/tpl/edit/{id?}");
      options.Conventions.AddPageRoute("/videosms/tpl/view", "/videosms/tpl/view/{id?}");
      //options.Conventions.AddPageRoute("/videosms/tpl/add", "/videosms/tpl/add");
})

和默认路由相同的话不要添加, 否则有可能会导致路由匹配冲突.

c# .Net Core 判断字符串是否为英文(包括符号)

做短信网关程序, 有英文和非英文短信的计费问题. 需要根据短信内容类型来确定条数.
英文短信为140个字符为一条, 非英文内容的则为70个字符为一条.
该方法的原理是根据字符编码规范来检查是否是纯英文字符.
UTF8编码规范中, 中文为3或者4位, ASCII字符为1位, 只需要将内容转换为UTF8码后判断长度是否和原内容一致即可.

public static bool IsEn(string content){
    if(string.IsNullOrWhiteSpace(content))
    {
        return false;
    }
    var bytes = Encoding.UTF8.GetBytes(content);
    bool result = bytes.Length == content.Length;
    return result;
}

示例代码如下

using System;
using System.Diagnostics;
using System.Text;

namespace ConsoleDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] arr = new[] {"张三", "zhangsan", "张三aa", "zhangsan123.//*-" };
            for (int i = 0; i < arr.Length; i++)
            {
                Console.WriteLine($"'{arr[i]}' 为 {(IsEn(arr[i])? "英文" : "非英文")}");
            }

            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < 100000; i++)
            {
                IsEn("zhangsan11111");
            }
            sw.Stop();
            Console.WriteLine($"英文循环10万次用时{sw.ElapsedMilliseconds} 毫秒");

            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            for (int i = 0; i < 100000; i++)
            {
                IsEn("张三zhangsan11111");
            }
            sw1.Stop();
            Console.WriteLine($"非英文循环10万次用时{sw1.ElapsedMilliseconds} 毫秒");
        }

        public static bool IsEn(string content)
        {
            if (string.IsNullOrWhiteSpace(content))
            {
                return false;
            }
            var bytes = Encoding.UTF8.GetBytes(content);
            bool result = bytes.Length == content.Length;
            return result;
        }
    }
}

执行结果

'张三' 为 非英文
'zhangsan' 为 英文
'张三aa' 为 非英文
'zhangsan123.//*-' 为 英文
英文循环10万次用时7 毫秒
非英文循环10万次用时7 毫秒

.Net Core 控制台程序读取appsettings.json

安装 nuget 包 Microsoft.Extensions.ConfigurationMicrosoft.Extensions.Configuration.FileExtensionsMicrosoft.Extensions.Configuration.Json
在main方法中执行如下代码

var conf = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true, true)
.Build();
var value = conf.GetSection("key").Value;

c# asp.net ip黑名单

短信验证码接口被恶意请求,写了一个简单的黑名单规则.
使用静态数组的形式实现,优点为不占用数据库资源且速度更快效率更高. 缺点为数据无持久化,网站重启后黑名单就清空了.
效果为: 如果指定时间内请求次数大于最大请求数并且发送的手机号码大于等于指定号码数量,则加入黑名单,时长为 {BlockTime}
根据如下属性进行配置后,
IsInBlackList方法为判断IP是否在黑名单内,返回bool
RecordRequest方法记录IP和手机号(可以根据功能自己修改具体功能),如满足列入黑名单条件,则自动列入黑名单, 返回bool. 如满足拉黑规则,则返回true,否则返回false

    public class IpBlock
    {

        /// <summary>
        /// 统计时间单位(秒)
        /// </summary>
        private const int Seconds = 60*50;//50分钟

        /// <summary>
        /// 单位时间内请求超出指定次数,则加入黑名单
        /// </summary>
        private const int RequestCount = 3;

        /// <summary>
        /// 单位时间内请求的手机号码数
        /// </summary>
        private const int RequestPhoneCount = 3;
        /// <summary>
        /// 黑名单时间 分钟
        /// </summary>
        private const int BlockTime = 60*24*7; //7天

        /// <summary>
        /// IP黑名单
        /// </summary>
        private static List<BlockedIp> BlackList;

        /// <summary>
        /// 请求详情
        /// </summary>
        private static List<IpRequestModel> RequestList;

        static IpBlock()
        {
            BlackList = new List<BlockedIp>();
            RequestList = new List<IpRequestModel>();
        }


        /// <summary>
        /// IP地址是否在黑名单中
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsInBlackList(string ip)
        {
            UpdateBlackList();
            return BlackList.FirstOrDefault(x => x.Ip.Equals(ip)) != null;
        }

        /// <summary>
        /// 记录请求信息并将符合的IP列入黑名单
        /// </summary>
        /// <param name="ip"></param>
        public static bool RecordRequest(string ip, string phone)
        {
            UpdateRequestList();
            RequestList.Add(new IpRequestModel
            {
                Ip = ip,
                RequestTime = DateTime.Now,
                Phone = phone
            });
            var requestRecord = RequestList.Where(x => x.Ip.Equals(ip));
            var count = requestRecord.Count();
            var phoneCount = requestRecord.Select(x => x.Phone).Distinct().Count();
            if (count >= RequestCount && phoneCount >= RequestPhoneCount)
            {
                AddToBlackList(ip);
                return true;
            }
            return false;
        }





        /// <summary>
        /// 更新黑名单
        /// </summary>
        private static void UpdateBlackList()
        {
            var expireList = BlackList.Where(x => x.ExpireTime < DateTime.Now).ToList();
            foreach (var item in expireList)
            {
                BlackList.Remove(item);
            }
        }

        /// <summary>
        /// 将IP列入黑名单
        /// </summary>
        /// <param name="ip"></param>
        private static void AddToBlackList(string ip)
        {
            var item = BlackList.FirstOrDefault(x => x.Ip.Equals(ip));
            if (item != null)
            {
                item.ExpireTime = DateTime.Now.AddMinutes(BlockTime);
            }
            else
            {
                BlackList.Add(new BlockedIp
                {
                    ExpireTime = DateTime.Now.AddMinutes(BlockTime),
                    Ip = ip
                });
            }
        }


        /// <summary>
        /// 更新请求信息
        /// </summary>
        private static void UpdateRequestList()
        {
            var expireList = RequestList.Where(x => x.RequestTime < DateTime.Now.AddSeconds(0-Seconds)).ToList();
            foreach (var item in expireList)
            {
                RequestList.Remove(item);
            }

        }

    }

    public class BlockedIp
    {
        /// <summary>
        /// IP地址
        /// </summary>
        public string Ip { get; set; }

        /// <summary>
        /// 过期时间
        /// </summary>
        public DateTime ExpireTime { get; set; }
    }

    public class IpRequestModel
    {
        /// <summary>
        /// IP地址
        /// </summary>
        public string Ip { get; set; }

        /// <summary>
        /// 请求时间
        /// </summary>
        public DateTime RequestTime { get; set; }

        /// <summary>
        /// 手机号
        /// </summary>
        public string Phone { get; set; }

    }

效果:

......
2018-08-31 10:47:51.007 INFO ASP.mobilergister_aspx: 发送验证码短信 时间:2018/8/31 10:47:51 IP地址:223.68.67.198 手机号码:177****8475
2018-08-31 10:50:55.412 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:50:55 IP地址:220.190.28.133
2018-08-31 10:50:58.302 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:50:58 IP地址:60.181.172.196
2018-08-31 10:51:00.474 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:00 IP地址:39.171.235.161
2018-08-31 10:51:14.037 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:14 IP地址:60.181.164.123
2018-08-31 10:51:15.677 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:15 IP地址:182.200.0.14
2018-08-31 10:51:21.037 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:21 IP地址:112.12.136.83
2018-08-31 10:51:23.724 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:23 IP地址:42.234.41.134
2018-08-31 10:51:25.802 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:25 IP地址:60.180.34.139
2018-08-31 10:51:28.443 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:28 IP地址:182.200.179.203
2018-08-31 10:51:31.130 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:31 IP地址:115.223.150.237
2018-08-31 10:51:39.990 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:39 IP地址:113.87.130.72
2018-08-31 10:51:46.771 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:46 IP地址:113.247.23.88
2018-08-31 10:51:47.990 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:47 IP地址:60.180.50.65
2018-08-31 10:51:52.459 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:52 IP地址:182.200.7.6
2018-08-31 10:51:57.506 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:51:57 IP地址:115.223.135.93
2018-08-31 10:52:07.008 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:52:07 IP地址:223.68.67.198
2018-08-31 10:52:08.758 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:52:08 IP地址:60.180.235.58
2018-08-31 10:52:28.555 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:52:28 IP地址:27.18.202.136
2018-08-31 10:52:59.367 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:52:59 IP地址:113.139.240.243
2018-08-31 10:55:06.790 INFO ASP.mobilergister_aspx: 发送验证码短信 时间:2018/8/31 10:55:06 IP地址:125.47.67.224 手机号码:130****1322
2018-08-31 10:55:34.775 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:55:34 IP地址:59.109.117.88
2018-08-31 10:57:40.229 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 10:57:40 IP地址:180.120.160.12
2018-08-31 11:02:21.105 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 11:02:21 IP地址:113.139.242.216
2018-08-31 11:14:03.632 INFO ASP.mobilergister_aspx: 发送验证码短信 时间:2018/8/31 11:14:03 IP地址:1.194.21.226 手机号码:130****2793
2018-08-31 11:27:52.295 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 11:27:52 IP地址:27.17.148.80
2018-08-31 11:31:31.718 INFO ASP.mobilergister_aspx: 发送验证码短信 时间:2018/8/31 11:31:31 IP地址:125.47.55.70 手机号码:130****1323
2018-08-31 11:31:40.968 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 11:31:40 IP地址:182.200.3.11
2018-08-31 11:31:45.843 INFO ASP.mobilergister_aspx: IP加入黑名单 时间:2018/8/31 11:31:45 IP地址:125.47.55.70
......

C# 静态构造函数实现单例

使用静态构造函数只执行一次的特性,创建单例

public class SingletonClass
{
    private SingletonClass()=> Thread.Sleep(1000);
    static SingletonClass()=> _instance = new SingletonClass();
    private static readonly SingletonClass _instance;
    public static SingletonClass GetInstance()=> _instance;
}

dnc(.Net core/Dot Net Core) 中使用automapper

最近在学习架构方面的知识,顺便先写一个基于dnc(.Net core/Dot Net Core)的单体架构.有用到Automapper,先记录一下
一.安装Nuget包:
1. AutoMapper
2. AutoMapper.Extensions.Microsoft.DependencyInjection
二.创建AutoMapper的profile类

public class MyProfile:Profile
{
    public MyProfile()
    {
        CreateMap<SysUser, SysUserDTO>();
        CreateMap<Advance, AdvanceDTO>();
    }
}

三.StartUp类中配置Automapper
1.如果使用单个profile类,在ConfigureServices方法中加入:

services.AddAutoMapper(config =>
{
    config.AddProfile<MyProfile>();
});

2.如果使用多个profile类或者profile在不同的项目中,则加入如下:

services.AddAutoMapper(config =>
{
    var types = Assembly
                    .GetEntryAssembly()
                    .GetReferencedAssemblies()
                    .Select(Assembly.Load)
                    .SelectMany(y => y.DefinedTypes)
                    .Where(type => typeof(Profile).GetTypeInfo().IsAssignableFrom(type.AsType())
                    && type.FullName.ToUpper().StartsWith("CHCMS")
                    && type.BaseType.Equals(typeof(Profile)));//CHCMS是我的项目命名空间开头部分,请修改为你项目的对应命名空间开头部分.
    var typeList = new List<Type>();
    foreach (var ti in types)
    {
        var type = ti.AsType();
        typeList.Add(type);
    }
    config.AddProfiles(typeList);
});

四.开始使用

var user = _dbContext.SysUser.Where(x => x.UserName.Equals(userName)).FirstOrDefault();
var userDto = Mapper.Map<SysUserDTO>(user);

.net coe 类库中使用ef core遇到的问题

1.提示”dotnet-ef未知命令”:
在csproj文件中新增itemgroup,加入如下:

<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />

2.dotnet ef migrations add xxx 时提示如下信息
The specified framework version ‘2.0’ could not be parsed
The specified framework ‘Microsoft.NETCore.App’, version ‘2.0’ was not found.
– Check application dependencies and target a framework version installed at:
\
– Alternatively, install the framework version ‘2.0’.
此信息的错误原因为未指定runtime版本号. 在 节点下加入如下:

<RuntimeFrameworkVersion>2.0.3</RuntimeFrameworkVersion>

版本号试项目而定
3. dotnet ef migrations add xxx时提示如下错误:
Unable to create an object of type ‘xxxDbContext’. Add an implementation of ‘IDesignTimeDbContextFactory‘ to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
此错误为,没有找到dbcontext的初始化信息,未指定所用数据库以及数据库链接字符串.
解决此问题需要在项目中 dbcontext同目录下增加 IDesignTimeDbContextFactory 接口的实现类

    public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<CHCmsDbContext>

    {
       

        public CHCmsDbContext CreateDbContext(string[] args)

        {

            var builder = new DbContextOptionsBuilder<CHCmsDbContext>();
           
            builder.UseMySql("Server=localhost;User=chcms;Password=123456;DataBase=CHCms;");

            return new CHCmsDbContext(builder.Options);

        }

    }

Xamarin调用百度SDK实现百度定位

Xamarin集成各方面第三方jar过程中都会有意想不到的各种问题,这里特地说明如何集成百度地图 ,希望可以帮到更多的初学者。

废话不多说,进入主题:

第一步(下载相关SDK):

  首先下载百度地图所需的SDK包,我这里是使用的v4.2,下载后会有一个文件夹,两个jar文件。首先我们需要的就是想办法将两个jar包转换为dll

第二步(转换jar包为dll):

    1、新建 Java Bindings Library 项目

    2.将 android-support-v4.jar , BaiduLBS_Android.jar 放到Jars文件夹下

    3.修改.jar其属性

      android-support-v4.jar转换属性设为:EmbeddedReferenceJar

BaiduLBS_Android.jar转换属性设为:EmbeddedJar

    5.生成项目,生成成功

到该项目的bin\Debug目录下拿到dll,得到了生成的dll,接下来就是我们说了算了,直接在项目中引用生成的dll,最好单独引用dll,不要引用项目,会有问题。

第三步:进行引用,实现定位

  1、新建App项目

  新建好项目后第一件事儿就是引用刚刚生成的dll。

  2、向AndroidManifest.xml 配置相关权限、f服务声明,ak秘钥信息
    打开AndroidManifest.xml文件:
    

   I.在根节点中加入以下权限:
     

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
      </uses-permission>
       <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" ></uses-permission>
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
        </uses-permission>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
        </uses-permission>
        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
        </uses-permission>
        <uses-permission android:name="android.permission.READ_PHONE_STATE" >
        </uses-permission>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
        </uses-permission>
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
        </uses-permission>
        <uses-permission android:name="android.permission.READ_LOGS" >
        </uses-permission>
        <uses-permission android:name="android.permission.VIBRATE" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />
        <uses-permission android:name="android.permission.WRITE_SETTINGS" />
        
      <service
               android:name="com.baidu.location.f"
               android:enabled="true"
               android:process=":remote" >
                <intent-filter>
                    <action android:name="com.baidu.location.service_v2.2" >
                    </action>
                </intent-filter>
        </service>

    III.加入ak秘钥信息,一样的在在节点中声明:
      
      

  3:在项目中新建libs文件夹,将下载的SDK包中的armeabi文件夹拷贝到该目录下
    
  4:将armeabi目录下的so文件的生成操作为AndroidNativeLibrary。

  5:最后一步,就是转换相关Demo里面的代码了,这个应该不需要多说了吧!定位的话转换以下两个.java文件即可。

6.运行,记住,要真机调试,AVD是定位不了的。运行结果如下:

    这样,就实现了Xamarin Android集成百度定位的相关操作了。自己开始也折腾了半天,烦躁死,总算功夫不负有心人,终于搞出来了,以防有其他朋友也需要实现该功能(我开始是使用的Android自带的定位服务,但总归是定位慢,还只有在比较开阔的地方才能正常点拿到位置信息),少走冤枉路,减少不必要的麻烦,特写出实现方法,如有什么问题,还请大家多多指教,多谢!!!

原文地址:http://www.cnblogs.com/lts-lts/p/4907967.html

[转]IOC(依赖注入)–入门篇

之前就听同事说过依赖注入(dependency injection)、控制反转(Inversion of Control)。起初听的是一头雾水,试着在项目中运用了几次,总算明白了一些,抛砖引玉,与大家分享一下拙见。

其实依赖注入和控制反转指的都是同一个事情。什么是依赖注入了???

【个人理解】

以最熟悉的三层架构的项目来说,BLL层依赖DAL层,UI层依赖于BLL层,层层之间紧密联系。代码里到处都是new 对象。认识IOC后,发现IOC最大的好处就是解耦了对这种层级之间的依赖关系进。程序本身不在负责对象的创建和维护,而交给外部容器(IOC容器)来负责。外部容器在运行时动态地将依赖的对象注入到组件之中。

简单的来说就是在类型A中需要使用类型B的实例,而B实例的创建并不由A来负责,而是通过外部容器来创建。相比以往实例化对象的写法,确实很爽。

以往实例化都是这样的:

public class A
{
    public A(B b)
    {
        this.B = b;
    }
 
    public B B { get; set; }
 
    public void Test(B b)
    {
        Console.WriteLine(b.ToString());
    }
}

A 类受B类的影响很大。A类的构造函数中,实例化B,且在A类的Test的方法中,需要判断B类是不是被实例化。A即创建B又需要维护B。用了IOC,解耦了这种依赖关系。接下来看看我在项目中是怎么简单应用的。

 

【项目简单试用】

一开始用的IOC容器是Unity,四个字,短小精干(用了有段日子。还有好多功能还需不断去探索) 。网上还有其它的IOC容器,没有去了解过(个人认为,能把一个工具用会,用熟,用精,才是王道。)

我把项目中的一段代码摘出来,项目需求大致上是项目有个数据统计,它下面有三种不同的统计类型,需要与数据库交互,然后展示到页面。

首先需要Unity的类库,利用VS2012的库程序包管理工具去下载Unity的类库。

项目的结构是这样,标准的是三层架构,BLL和DAL都有接口层IBLL,IDAL。

首先我们按照不用IOC的方式来实现这个小需求。

IDAL,IBLL 创建接口?IAnalyse 接口里有个方法

public interface IAnalyse
    {
        /// <summary>
        /// 显示结果
        /// </summary>
        void ShowResult();
    }

DAL 层引用IDAL,创建类?Analyse.cs

public class Analyse:IDAL.IAnalyse
    {
        public void ShowResult()
        {
            Console.WriteLine("分析底层数据库交互");
        }
    }

BLL层引用IDAL,DAL,IBLL 创建?类?Analyse.cs

        /// <summary>
        /// 显示结果
        /// </summary>
        public void ShowResult()
        {
            ////以前思路 需要引用IBLL,IDAL,DAL
            IDAL.IAnalyse dal = new DAL.Analyse();
            dal.ShowResult();
        }

UI层用控制台应用程序来代替。需引用IBLL,BLL

class Program
    {
        static void Main(string[] args)
        {
            OldMethod();
            Console.ReadKey();
        }

        /// <summary>
        /// 在使用IOC前的写法。需要引入IBLL,BLL
        /// </summary>
        static void OldMethod()
        {
            IBLL.IAnalyse bll = new BLL.Analyse();
            bll.ShowResult(); 
        }
    }

按照以前的方法,每个层我们都在不断的new 对象。写到这里发现这些都是很中规中矩的写法,以前老师教的也是这样,可能你会觉得没啥不好的。我就假如:BLL.Analyse 的构造函数需要参数,参数为Class B ,去掉无参的构造函数,你是不是所有new 对象的地方都要更改。小项目也许还没有问题,如果是上百万的大项目咋办。这就是所谓的层与层之间的耦合度高。(个人拙见,多多指教)

接下来我们用 IOC 来解耦。在Program.cs 增加?IOCMethod1 方法

static void Main(string[] args)
        {
            //OldMethod();
            IOCMethod1();
            Console.ReadKey();
        }

static void IOCMethod1()
        {
            IUnityContainer container=new UnityContainer();
            ////在容器中注册一种类型,它是一个类型的映射,接口类型是IAnalyse,希望返回的类型是Analyse
            container.RegisterType<IBLL.IAnalyse, BLL.Analyse>();
            ////第二种写法
            //container.RegisterType(typeof (IBLL.IAnalyse), typeof (BLL.Analyse));
            IBLL.IAnalyse bll = container.Resolve<IBLL.IAnalyse>();
            bll.ShowResult();
        }

使用unity就三步:

第一,new IOC 容器

第二,调用RegisterType 注册类型。这里有多种注册形式。可以注册单例的、构造函数有参数的。

第三,调用Resolve 创建对象

(认识IOC 简单吧 O(∩_∩)O)

到这,你会发现,UI层 仍然引用了IBLL,BLL,RegisterType方法需要这两个类库。既然是解耦,就得解耦彻底些。有什么方法???

我在Core层?DependencyRegister.cs. 建立一个静态方法,在程序运行开始的时候,注册所有的类型。UI 层移除BLL ,引用Core

namespace Core
{
    /// <summary>
    /// 类型注册
    /// </summary>
    public class DependencyRegister
    {


        public static IUnityContainer DependencyRegisterContainer()
        {
            IUnityContainer container = new UnityContainer();
            container.RegisterType<IBLL.IAnalyse, BLL.Analyse>()
                     .RegisterType<IDAL.IAnalyse, DAL.Analyse>();
            return container;
        }
    }
}


////UI层 先移除BLL,引用Core
static void Main(string[] args)
        {
            
            IOCMethod2();
            Console.ReadKey();
        }

static void IOCMethod2()
        {

  IUnityContainer container = DependencyRegister.DependencyRegisterContainer();
IBLL.IAnalyse bll = container.Resolve<IBLL.IAnalyse>(); 
bll.ShowResult(); 
    }

这样达到了解耦的目标,如何需要更改类的构造函数,只需更改Core?DependencyRegister.cs 就可以了。

 

【其它解耦方式】

建立core是用了自己得方法来实现解耦的,其实unity还有更觉得,通过配置文件 app.config 来实现。用的是?Microsoft.Practices.Unity.Configuration.dll

    <!-- 程序集-->
    <assembly name="IBLL"/>
    <assembly name="IDAL"/>
    <!--要返回的类型-->
    <alias alias="BLLAnalyse1" type="BLL.Analyse, BLL" />
    <container name="ContainerAnalyse">
      <register type="IBLL.IAnalyse" name="BLLAnalyse1" mapTo="BLLAnalyse1" />
    </container>
private static void IOCMethod3()
        {
            ////通过配置文件注册所有类型
            IUnityContainer container=new UnityContainer();
            UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Configure(container, "ContainerAnalyse");
            IBLL.IAnalyse bll = container.Resolve<IBLL.IAnalyse>("BLLAnalyse1");
            bll.ShowResult();
        }

【投机取巧】

无论是使用全局方法,或者 配置文件,都是注册类的形式不同。每种方法都需要调用Resolve 来创建对象。有没有连改方法都不用调用的形式。

不用多说,直接上代码:

namespace BLL
{
    public class Analyse:IBLL.IAnalyse
    {
        ////使用依赖注入
        [Dependency]
        public IDAL.IAnalyse dal { get; set; }
        /// <summary>
        /// 显示结果
        /// </summary>
        public void ShowResult()
        {
            ////以前思路 需要引用IBLL,IDAL,DAL
            //IDAL.IAnalyse dal = new DAL.Analyse();
            
            
            dal.ShowResult();
        }
    }
}

使用[Dependency]属性。说实话,它的用法还有些没有弄明白。希望明白这个得多指教指教。

献丑了,有什么不对的地方希望大家多多指教。Unity 功能很多,这篇只不过是凤毛麟角,还有什么构造注入,属性注入、单例的应用。这些,将在下篇继续分享。希望大家继续关注,多多指教。

【源码下载】

 

原文:http://www.cnblogs.com/ttrjba/p/3511935.html