C#

.NET Standard / Core 项目发布 NuGet 包并使包中的配置文件自动生成到 Bin 下

之前在如何创建 NuGet 包的文章中,曾经提到如何将配置文件(文件夹)包含到 NuGet 包中,并在用户安装了这个 NuGet 包并 build 自己工程后,自动将 Config 文件夹复制到 Bin 下。但是当时我并没有找到 .NET Standard 或 .NET Core 项目的配置方法,因此 Squirrel Framework 只能选择通过 .NET Framework 4.6.2 项目形式生成 NuGet 包(.NET Framework 下 NuGet 的配置方式请查看这篇文章《如何在 NuGet 发布自己的类库包》)。

不过最近有时间,通过半天的尝试终于将 4.6.2 的工程切换到 .NET Standard,这次的关键点在于不必自己去写 .nuspec 配置文件之后通过 dotnet pack 命令进行 build,而是改为直接通过编辑项目文件(.csproj)并通过 Visual Studio 在每次 build 时,自动完成 NuGet 包的生成。具体配置步骤如下:

Continue reading

Squirrel Framework 1.0.13 说明文档

Squirrel Framework – 是一个轻量级的 MongoDB 存储封装类库。同时,它还尝试为使用者提供了一系列的拓展类,方便日常的 .NET 开发需求。它致力于让你轻松、快速地构建基于 MongoDB 的应用程序。

下面我们简单介绍一下 Squirrel Framework 的核心功能,只要以下 4 个步骤,你就能完成持久化层的开发。

Continue reading

GitHub 提交忽略规则

我们可以在代码库的根目录创建一个名为 “.gitignore” 的文件,并在其中配置哪些文件或文件夹可以在提交的时候被忽略。以 .NET 项目为例,我们需要忽略与 VS 或 调试编译有关的 bin\obj\packages\.vs 等文件或文件夹,则只需要:

**/bin
**/packages
**/obj
**/.vs
*.bak
*.user
*.suo

注意,按行配置约束,一行一个。

一键清除 .NET 无用文件,清爽一夏

工作几年,电脑里会有很多项目代码,随之而来的就是许许多多调试、编译时带来的 bin/obj/package 或者 .vs 文件(夹),如何清除这些文件,来一个大扫除呢?这里提供一个超有效的 Batch 脚本供参考。

@echo off
REM start to clean code folder
echo Start to clean all code folder

@for /d /r %%c in (obj) do @if exist "%%c" (@rd /s /q "%%c" & echo Delete %%c)
@for /d /r %%c in (bin) do @if exist "%%c" (@rd /s /q "%%c" & echo Delete %%c)
@for /d /r %%c in (packages) do @if exist "%%c" (@rd /s /q "%%c" & echo Delete %%c)
@for /d /r %%c in (.vs) do @if exist "%%c" (@rd /s /q "%%c" & echo Delete %%c)

echo Done.

存储为 .bat 文件后,通过命令提示符运行,在我的电脑上运行后,整整节约了 15G 的磁盘空间,泪流满面!

如何在 NuGet 发布自己的类库包

我们可以将自己实现的类库发布到 NuGet 上,方便在未来开发应用程序时,对已有代码或结构进行复用。以下是在 NuGet 发布自己类库的一个简单介绍。

1. 首先,我们需要到 nuget.org 注册并 获取 API key

2. 随后,下载 NuGet 命令行工具,建议将 nuget.exe 注册到系统的环境变量中,方便后续步骤的操作
Continue reading

最佳实践:根据条件获取集合的部分结果

很多场景下,我们需要根据一个条件判定某一集合中是否存在从中选取部分符合条件的元素用于后续操作。我们有很多方式可以实现这种需求,比如 纯手工对集合进行遍历,yield return,Any(),Count() 或 Count 属性,那么,这些实现方式对效率的影响如何?哪种实现效率较优呢?

我们来做一次实验。

首先我们定义一个类,并初始化包含有 1 万个该类型实例的集合。

    public class Item
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public bool Gender { get; set; }
        public int Age { get; set; }
        public DateTime Birthday { get; set; }
        public string Address { get; set; }
        public string Email { get; set; }
    }

Continue reading

如何将 XML 的 XSD 定义转换为 C# 类

当我们将一些配置数据存储在 XML 文档中,或希望自定义某种 XML 格式的文档时,最好先去定义 XML 对应的 XSD 规范。定义 XSD 后,我们不仅可以在 VS 等 IDE 中对相应的 XML 文件的语法进行自动检查或属性匹配,同时也可以自动生成对应的实体类,简化 XML 的创建、修改以及读取。

打开 VS,在 XSD 文件上点击鼠标右键,点选 Open Command Prompt

Continue reading

C#: 一个方法执行超时 timeout 检查的实现

我们经常有这样的需求:如果一个方法的执行,超过了一个设定时间(timeout)就需要立即返回不再继续,这里我利用 C# 异步委托的 AsyncWaitHandle 来尽量简便的实现这一需求。

具体实现如下。注意,这里需要被调用的方法遵守 delegate TR TimeOutDelegate(T param); 形式的方法签名,如有其他需要,可以自行定制也很方便。

namespace TimeOutHelper
{
    #region using directives

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Threading;

    #endregion using directives

    internal class Program
    {
        public delegate TR TimeOutDelegate<in T, out TR>(T param);

        private static void Main()
        {
            Dictionary<Guid, string> result;
            Console.WriteLine(TimeoutFunction.Execute(Test, "Hello, World!", out result, TimeSpan.FromSeconds(3)));
            Console.WriteLine("Hello, World!");
            Console.ReadKey();
        }

        public static Dictionary<Guid, string> Test(string sourceString)
        {
            var result = sourceString.ToDictionary(
                character => Guid.NewGuid(),
                character => character.ToString(CultureInfo.InvariantCulture));
            Thread.Sleep(4000);
            return result;
        }

        public static class TimeoutFunction
        {
            /// <summary>
            ///     Execute a method with timeout check
            /// </summary>
            /// <typeparam name="T">Target method parameter type</typeparam>
            /// <typeparam name="TR">The result type of execution</typeparam>
            /// <param name="timeoutMethod">Target method</param>
            /// <param name="param">Target method parameter</param>
            /// <param name="result">The result of execution</param>
            /// <param name="timeout">Set timeout length</param>
            /// <returns>Is timeout</returns>
            public static Boolean Execute<T, TR>(
                TimeOutDelegate<T, TR> timeoutMethod, T param, out TR result, TimeSpan timeout)
            {
                var asyncResult = timeoutMethod.BeginInvoke(param, null, null);
                if (!asyncResult.AsyncWaitHandle.WaitOne(timeout, false))
                {
                    result = default(TR);
                    return true;
                }
                result = timeoutMethod.EndInvoke(asyncResult);
                return false;
            }
        }
    }
}

C#: 字符串连接 (+=) 与 StringBuilder 效率分析

在 C# 或 Java 中,我们可以使用诸如 StringBuilder, StringBuffer 等方式对大量字符串进行拼接操作。当然,我们也可以直接使用 字符串连接 (+=) 的方式进行拼接操作。但是,两种主要方式在效率上有何区别呢?我们是否需要针对这两类方式进行区别场景的使用呢?针对于此,我做了如下测试,以证明两种不同方式连接字符串的效率临界值。(关于Java中StringBuilder和StringBuffer的区别,可以参阅这篇文章

测试方法是:重复连接字符串 “Hello World!” 1次到40次,在每次连接的过程中都分别采用 String Connection (+=) 和 StringBuilder 的 Append()方法进行1000次,并分别计算出两种方法在这1000次运算过程中的获胜比率。通过多次试验,得到如下统计:

第一次:
StringBuilder Efficiency Test 1
Continue reading

ADFS 概念与基本开发介绍 (1)

(如您转载本文,必须标明本文作者及出处。如有任何疑问请与我联系 me@nap7.com

ADFS 相关开发技术的中文资料相对匮乏,之前在弄这个东西的时候搞的比较辛苦,因此总结此文档,以解后人之忧。

本文会首先介绍与联合身份验证有关的概念及相关的系统设计意图,随后会对 ADFS 联合身份验证的配置过程、结构及处理流程进行阐述。然后会基于已有的系统提出一个支持多 ADFS 联合身份验证的改进实例,并对其结构及处理流程进行阐述。最后会对开发过程中所遭遇的一些问题进行介绍。真诚希望本文能够帮助读者较快地了解联合身份验证的相关知识。

一 ADFS 基本概念与设计意图

1 基本概念阐述

1.1 联合身份验证

联合身份验证(Federated Identity)是一种用户身份的验证方式,这种验证方式通过把用户身份的验证过程与被该用户访问的服务提供商(SP,Service Provider,如我们自己的站点)进行逻辑分离,在保证用户身份信息被隔离在用户所属系统的内部的同时,为受信任的服务提供商提供所需要的用户信息。
当服务提供商需要对用户的身份进行验证时,会将相关的验证过程转交给身份验证提供方(IdP,Identity Provider,如AvePoint域的 AD FS 验证服务),当用户经由身份验证提供方成功登录后,身份验证提供方会将用户的身份验证凭据和用户相关的信息返还给服务提供商,从而实现服务提供商对于用户身份的验证,以及对于用户信息获取。
常见的联合身份验证的实现有SAML、OAuth、OpenID等方式,本文主要介绍的是基于Claims和SAML 2.0的 AD FS 联合身份验证。在基于Claims的联合身份验证的过程中,当身份验证提供方完成对于用户身份的验证,返还用户的相关信息时,其数据信息实体被称之为令牌(Token),其中的相关信息字段被称为声明(Claims)。令牌保证了用户身份的真实性,并包含了实用信息,其结构如下图所示。

ADFS_Claims
Continue reading

C#: 双检锁 (Double Checked Locking)

以下内容是我在公司作为新人培训讲师时对于作业的一次评价,简单介绍了双解锁的作用,可以作为一个简单的参考。

大家可以思考这样一个问题,一个程序可以对应多少个日志文件?对于我们这个小程序来说1个就够了,很多同学在设计Logger类的时候都是在构造方法或初始化方法中生成日志文件的,也就是说,这基本上等价于一个Logger的实例对应一个新的日志文件(或重新对同一文件重新开启流)。

Logger myLogger = new Logger(@“D:my.log”);

如何才能阻止Logger被随意的new出实例呢?我们可以修改Logger的构造方法,让构造方法成为private的,这样就能实现谁都不能new出Logger实例的目的了。但是,访问修饰符(如private)只是影响类之外的使用,对于Logger类的内部,是不会受到private的影响的,也就是说,我们依然可以在Logger类中使用new来创建实例,这正是我们想要的,我们可以为用户提前创建好一个实例,并作为这个类的静态成员存在,从而得到这样一个Logger类:
Continue reading