Git使用總結 Asp.net生命週期與Http協議 託管代碼與非託管代碼的區別 經過IEnumerable接口遍歷數據 依賴注入與控制反轉 C#多線程——優先級 AutoFac容器初步 C#特性詳解

一,原理php

首先,咱們要明白Git是什麼,它是一個管理工具或軟件,用來管理什麼的呢?固然是在軟件開發過程當中管理軟件或者文件的不一樣版本的工具,一些做家也能夠用這個管理本身創做的文本文件,由Linus開發的,也是Linux系統開發所用到的分佈式版本控制軟件。一說到分佈式,其實就是每一個電腦都有這麼個版本庫,而摒棄了傳統的中心文件系統服務,因此每一個人都能保存、還原以前的版本。在航天二院實習的時候,mentor讓我改一個軟件的Bug,因爲國企沒有外網,因此不能用github,院裏面也沒有搭建本身的Git文件服務器,因此每次改Bug以前都要備份一個以前的版本,以日期命名,並且後面還容易忘記那個版本有哪些功能模塊,就咱們兩我的開發一個軟件都把版本搞錯了好幾回,真心頭痛。css

git1_thumb[2]

二,Git經常使用命令html

git的經常使用命令有:init、add、rm、mv、commit、push、pull、clone、log、checkout、megre、status、branch、diff、config、remote、fetch、reset、tag、show、stash、grep、rebase、gc等。java

 

1,本地操做linux

Git命令 解釋 撒旦法備註
git init 初始化Git環境 先cd到要管理的文件夾中
git add *.txt / . 添加文件到暫存區 . 是將全部文件都添加到暫存區
git status 查看文件的狀態  
git commit -m 'First commit' 提交更新到版本庫 -m 是message的縮寫,即每次添加更新的備註
git log 查看提交更新的記錄  
git rm *.txt 刪除文件  
git mv a.txt b.txt 修改文件名 將a.txt的文件名改成b.txt

 

2,遠程操做git

Git命令 解釋 撒旦法備註
git config --global user.name "your name" 設置username,由於github每次commit都會記錄他們 github註冊時的用戶名
git config --global user.email "your_email@youremail.com" 設置email github註冊時的郵箱地址
git remote add origin https://...git 查看文件的狀態與Github創建遠程鏈接 如今github網站上創建倉庫
git push -u origin master 提交推送到Github的倉庫中 master分支能夠是其餘分支
   

 

在遠程操做Github以前要進行ssh key的配置,網上有不少教程能夠參考。大概分三步:程序員

  • 在本地建立ssh key,$ ssh-keygen -t rsa -C "your_email@youremail.com" (github網站上註冊的郵箱),回車後會在當前用戶.ssh文件夾下生成id_rsa、id_rsa.pub、known_hosts三個文件github

  • 打開id_rsa.pub,複製裏面的key, 回到github網站,進入Account Settings,左邊選擇SSH Keys,Add SSH Key, Title隨便填,粘貼key。web

  • 驗證是否成功,在本地git bash下輸入,$ ssh -T git@github.com ,回車就會看到:You’ve successfully authenticated, but GitHub does not provide shell access 。這就表示已成功連上github。shell

參考連接:

git中sshkey有何做用?

http://www.bootcss.com/p/git-guide/

 

Git命令腦圖(圖片來自Github)

Git_V2.16.2

 

3,Git分支管理模型Pic

git分支管理模型_thumb[3]

三,Demo

1,初始化一個git倉庫,新建一個code.txt文件,提交到git版本庫,如今git開始管理code.txt文件了

 
ckjbug@ckjbug MINGW64 ~/Desktop

$ mkdir gituse

ckjbug@ckjbug MINGW64 ~/Desktop

$ cd gituse

ckjbug@ckjbug MINGW64 ~/Desktop/gituse

$ git init

Initialized empty Git repository in C:/Users/Enz/Desktop/gituse/.git/

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

No commits yet

Untracked files:

  (use "git add <file>..." to include in what will be committed)

code.txt

nothing added to commit but untracked files present (use "git add" to track)

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git add code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

No commits yet

Changes to be committed:

  (use "git rm --cached <file>..." to unstage)

new file:   code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git commit -m 'First commit'

[master (root-commit) 0f67f2c] First commit

 1 file changed, 0 insertions(+), 0 deletions(-)

 create mode 100644 code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

nothing to commit, working tree clean
 

2,修改文件,在code.txt添加一行代碼,而後用checkout回到修改前(即沒有添加代碼前的版本,這裏以前寫入的代碼沒有了,空文本),這只是checkout的一種用法,更可能是後面學習的git的分支轉換。

 
ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

Changes not staged for commit:

  (use "git add <file>..." to update what will be committed)

  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   code.txt

no changes added to commit (use "git add" and/or "git commit -a")

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git checkout -- code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ notepad code.txt
 

3,仍是上面這個功能,回到文本修改前的狀態,可是咱們修改文件後已經添加到暫存區了,這時使用git checkout code.txt已經沒用了,能夠用git reset回到沒有添加到暫存區的狀態(最初始的狀態)

 
ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ clear

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

Changes not staged for commit:

  (use "git add <file>..." to update what will be committed)

  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   code.txt

no changes added to commit (use "git add" and/or "git commit -a")

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git add code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git checkout code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git reset

Unstaged changes after reset:

M       code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

Changes not staged for commit:

  (use "git add <file>..." to update what will be committed)

  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   code.txt

no changes added to commit (use "git add" and/or "git commit -a")

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git checkout -- code.txt
 

4,添加、切換、刪除分支(添加develop開發者的工做分支)

 
ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch

* master

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch develop

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch

  develop

* master

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git checkout develop

Switched to branch 'develop'

M       code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git branch

* develop

  master

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git checkout master

Switched to branch 'master'

M       code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch

  develop

* master

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch -d develop

Deleted branch develop (was 0f67f2c).

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch

* master
 

5,新建一個開發者develop分支,而後添加develop.txt文本,添加到暫存庫,提交,最後轉換到master分支,發現develop.txt文本不見了,這就是版本管理,每一個分支控制一個版本,當咱們轉回到develop分支下時這個devel.txt文件又出現了。若是咱們在develop分支下修改了master分支的code.txt,當咱們轉換爲master分支上時,不會出現develop分支下的修改。

 
ckjbug@ckjbug MINGW64 ~/Desktop/gituse

$ git init

Initialized empty Git repository in C:/Users/Enz/Desktop/gituse/.git/

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

No commits yet

Untracked files:

  (use "git add <file>..." to include in what will be committed)

code.txt

nothing added to commit but untracked files present (use "git add" to track)

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git add .

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

No commits yet

Changes to be committed:

  (use "git rm --cached <file>..." to unstage)

new file:   code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git commit -m 'First commit'

[master (root-commit) 2571887] First commit

 1 file changed, 0 insertions(+), 0 deletions(-)

 create mode 100644 code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git status

On branch master

nothing to commit, working tree clean

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch

* master

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git branch develop

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git checkout develop  //以後添加一個develop.txt文件

Switched to branch 'develop'

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git branch

* develop

  master

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git status

On branch develop

Untracked files:

  (use "git add <file>..." to include in what will be committed)

develop.txt

nothing added to commit but untracked files present (use "git add" to track)

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git add develop.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git commit -m 'add a develop_txt on branch develop'

[develop 2fd0d60] add a develop_txt on branch develop

 1 file changed, 0 insertions(+), 0 deletions(-)

 create mode 100644 develop.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git branch

* develop

  master

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git checkout master

Switched to branch 'master'

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git checkout develop  //在develop分支下修改master分支下的code.txt文件

Switched to branch 'develop'

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git status

On branch develop

Changes not staged for commit:

  (use "git add <file>..." to update what will be committed)

  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   code.txt

no changes added to commit (use "git add" and/or "git commit -a")

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git add code.txt

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git commit -m '在develop分支下修改了master分支的code.txt文件'

[develop 903c8e0] 在develop分支下修改了master分支的code.txt文件

 1 file changed, 1 insertion(+)

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git status

On branch develop

nothing to commit, working tree clean

ckjbug@ckjbug MINGW64 ~/Desktop/gituse (develop)

$ git checkout master   //此時code.txt修改的代碼不在了

Switched to branch 'master'
 

Image

 

6,融合分支,在master分支上時,將develop分支merge到master分支上。這時develop.txt文件出現了。即融合到了master分支中。

 
ckjbug@ckjbug MINGW64 ~/Desktop/gituse (master)

$ git merge develop

Updating 2571887..903c8e0

Fast-forward

 code.txt    | 1 +

 develop.txt | 0

 2 files changed, 1 insertion(+)

 create mode 100644 develop.txt
 

7,Merge時衝突的處理,加入兩個不一樣分支同時修改了主分支下code.txt中的第三行代碼,兩個分支在融合時會衝突。

解決衝突的參考連接:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840202368c74be33fbd884e71b570f2cc3c0d1dcf000

 

8,遠程推送push、拉取pull項目代碼,在實際項目中,每每已經存在了遠程的項目,當你參與到項目的開發當中時,

若是咱們將一個Github已經存在的項目clone下來,而後修改後與遠程倉庫鏈接,出現這樣的錯誤:fatal: remote origin already exists. 則能夠輸入 git remote rm origin後重新創建鏈接。
參考連接:

http://www.javashuo.com/article/p-mgrqqypj-ev.html

 

split

相關連接:

在線教程【廖雪峯】

知乎

 

__EOF__

做  者:ckjbug
出  處:http://www.javashuo.com/article/p-pcihfsmr-km.html
關於博主:編程路上的小學生,熱愛技術,喜歡專研。評論和私信會在第一時間回覆。或者直接私信我。
版權聲明:署名 - 非商業性使用 - 禁止演繹,協議普通文本 | 協議法律文本
聲援博主:若是您以爲文章對您有幫助,能夠點擊文章右下角推薦】一下。您的鼓勵是博主的最大動力!

 

 

 

Asp.net生命週期與Http協議

 

Http協議,底層的東西仍是不是特別熟悉,感受要通過沉澱以後才能理解這些東西吧

1.Asp.net生命週期

Asp.net生命週期:

從發起請求開始,到IIS進行處理的所有過程,而後再到獲取結果

當請求一個*.aspx文件的時候,這個請求會被inetinfo.exe進程截獲,它判斷文件的後綴(aspx)以後,將這個請求轉交給ASPNET_ISAPI.dll,ASPNET_ISAPI.dll會經過http管道(Http PipeLine)將請求發送給ASPNET_WP.exe進程,在ASPNET_WP.exe進程中經過HttpRuntime來處理這個請求,處理完畢將結果返回客戶端。     inetinfo.exe進程:是www服務的進程,IIS服務和ASPNET_ISAPI.DLL都寄存在此進程中。     ASPNET_ISAPI.DLL:是處理.aspx文件的win32組件。其實IIS服務器是隻能識別.html文件的,當IIS服務器發現被請求的文件是.aspx文件時,IIS服務器將其交給aspnet_isapi.dll來處理。     aspnet_wp.exe進程:ASP.NET框架進程,提供.net運行的託管環境,.net的CLR(公共語言運行時)就是寄存在此進程中。

ASP.NET Framework處理一個Http Request的流程:     HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()
ASP.NET請求處理過程是基於管道模型的,這個管道模型是由多個HttpModule和HttpHandler組成,ASP.NET把http請求依次傳遞給管道中各個HttpModule,最終被HttpHandler處理,處理完成後,再次通過管道中的HTTP模塊,把結果返回給客戶端。咱們能夠在每一個HttpModule中均可以干預請求的處理過程。

 

 

2.Htpp協議的生命週期

這個感受要後續繼續加深理解以後再進行補充吧,目前就拿別人的思路來解答這個過程

 

1.輸入url,瀏覽器DNS解析域名,獲取ip

2.三次握手,創建tcp連接

3.向服務端發送http請求

4.服務端處理請求並響應

5.瀏覽器渲染HTML

6在渲染的過程當中繼續加載css,js,圖片,音頻,視頻文件

7 呈現給用戶

 

 

託管代碼與非託管代碼的區別

 

實際上是知道這個東西,可是不知道專業術語竟然叫這個,我覺得是Azure雲託管,好吧,開個玩笑

不止C#,java也是託管代碼啊,重點,重點,重點!!!

1.簡單的說,就是代碼被編譯成MSIL後在.net的Framework下運行,同操做系統底層的交互都交給framework去作。所謂非託管代碼就是脫離了Framework的管制,

直接同底層API打交道,本身管理本身的內存和安全機制等東西。而託管代碼就無論這些,全都由Framework去完成

2.「程序」通常都是在對操做系統進行直接或者間接的操做
「託管程序」是須要經過訪問公共語言運行時(cls)才能訪問操做系統的程序
而「非託管程序」不用經過訪問公共語言運行時(cls)能夠直接訪問操做系統的程序

3.vb.net,C#等寫的程序是託管程序,VC++能夠寫託管程序,若是用到了內存管理,則只能編譯爲非託管程序這些東西MSDN都有描述

 

 

 

經過IEnumerable接口遍歷數據

 

使用IEnumerable接口遍歷數據,這在項目中會常常的用到,這個類型呢主要是一個枚舉器。

1.首先須要讓該類型實現一個名字叫IEnumerable的接口,實現該接口的主要目的是爲了讓當前類型中增長一個名字叫GetEnumerator()的方法。

複製代碼
public class Person : IEnumerable
    {
        private string[] Friends = new string[] { "張三", "李四", "王五", "趙六" };

        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
        public string Email
        {
            get;
            set;
        }

        #region IEnumerable 成員

        //這個方法的做用就是返回一個「枚舉器」
        public IEnumerator GetEnumerator()
        {
            return new PersonEnumerator(this.Friends);
        }

        #endregion
    }
複製代碼

2.但願一個類型被枚舉遍歷,就是要實現一個枚舉器方法

複製代碼
public class PersonEnumerator : IEnumerator
    {
        public PersonEnumerator(string[] fs)
        {
            _friends = fs;
        }
        private string[] _friends;

        //通常下標都是一開始指向了第一條的前一條。第一條是0
        private int index = -1;


        #region IEnumerator 成員

        public object Current
        {
            get
            {
                if (index >= 0 && index < _friends.Length)  //下標有範圍
                {
                    return _friends[index];
                }
                else
                {
                    throw new IndexOutOfRangeException();
                }
            }
        }
       
        public bool MoveNext()
        {
            if (index + 1 < _friends.Length)     //下標有範圍
            {
                index++;
                return true;
            }
            return false;
        }

        public void Reset()
        {
            index = -1;
        }

        #endregion
    }
複製代碼

3.而後進行遍歷,這裏呢能夠調用本身封裝的MoveNext方法去找數組元素

複製代碼
 Person p = new Person();

            IEnumerator etor = p.GetEnumerator();
            while (etor.MoveNext())
            {
                Console.WriteLine(etor.Current.ToString());
            }
複製代碼

也能夠直接使用foreach,並且主要是由於是枚舉元素,相似與數組,list等等之類的,均可以使用Lambda表達式來進行數據的處理

複製代碼
 Person p = new Person();
            foreach (string item in p)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("ok");
複製代碼

4.輸出的結果以下:

 

 

依賴注入與控制反轉

 

         反正這個概念我通常都是不去記得,首先看一下什麼是依賴:

有一個類是Animal,而後我定義了一個BlackCat類,類裏面有一個BlackCat方法,那麼這裏的BlackCat就依賴Animal

複製代碼
public class BlackCat
{
     public BlackCat(Animal  Cat)
     {
          Cry();
     }  
}
複製代碼

           BlackCat類實例化的時候須要一個Animal的對象做爲構造函數的參數,那麼BlackCat就依賴Animal,這就叫依賴

固然,不用構造函數的方式,在BlackCat類內部去new一個Animal,也是依賴;固然注入的話,就像是你寫了一個類,而後

經過IOC框架,把這個類注入到其餘類中,這就是注入

 

           控制反轉的意思就好理解了,就好比我定義了一個類,類裏面有一個方法,而後我如今要把這個方法的控制權交給別人來使用,這就是控制反轉。

在編寫代碼的時候,咱們須要把一些接口編寫成通用的道理就在這裏了,便於作到代碼複用

下面即以貓的例子來進行解說控制反轉

1.先定義一個動物類

複製代碼
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IOC
{
    class Animal
    {
        public void Cry()
        {
            Console.Write("動物喊叫");
        }
    }
}
複製代碼

2.定義一個貓的類

複製代碼
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IOC
{
    class Cat:Animal
    {
        public void Cry()
        {
            Console.WriteLine("動物喊叫");
        }
    }
}
複製代碼

3.我用實例化一個動物類,而後查看結果

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IOC
{
    class Program
    {
        static void Main(string[] args)
        {
            Animal A = new Cat();
            A.Cry();
            Console.ReadLine();
        }
    }
}
複製代碼

4.能夠看到我用子類能夠替換掉父類,也能夠用父類替換掉子類,其實並無太大的影響

Animal A = new Cat();

能夠看見輸出結果以下

 

C#多線程——優先級

 

       在個人公司這裏,由於要跟不少特殊的設備打交道,因此會用到多線程的東西,那麼咱們在進行多線程處理的時候,怎麼去設置優先級

我這裏用聽歌和下載小說作了個例子,咱們用電腦的時候確定是能夠邊聽歌邊下載小說的,那麼這就須要並行,有個問題就是我想優先聽

歌,下載小說對我來講不是那麼急的話我就能夠對兩個事情進行優先級的管控。

        線程裏有個屬性Priority能夠用來設置優先級,我設置線程1的優先級高於線程2的優先級,那麼線程1就會比線程2多運行一段時間,這個是人眼觀察不出來的

運行速度,CPU運行速度可不是能用人眼查看的

複製代碼
            bool b = true;
            int i=0, j=0;
            string Song = "";
            string Download = "";
            Thread Thread1=new Thread(() =>
            {
                while (b)
                {
                    Song="一百萬個可能";
                    i++;
                    
                }
            })
            {
                Name = "Thread1",
                Priority = ThreadPriority.Highest
            };
             Thread Thread2=new Thread(() =>
            {
                while (b)
                {
                    Download = "小說三體";
                    j++;
                }
            })
            {
                Name = "Thread2",
                Priority = ThreadPriority.Lowest
            };
            Thread1.Start();
            Thread2.Start();
            Thread.Sleep(1000);
            b = false;
            Console.WriteLine("Song: {0}, Download: {1}", Song, Download);
            Console.WriteLine("歌曲的優先級:{0}",i);
            Console.WriteLine("下載的優先級:{0}",j);
            Console.ReadLine();
複製代碼

這裏咱們看一下執行結果

從結果中能夠看到,優先級高的線程獲得運行的次數比優先級低的線程多,但即便是最低優先級的線程都有很大的機會來執行。

 

 

AutoFac容器初步

 

轉載請註明出處,AutoFac:最流行的依賴注入和IOC框架,輕量且高性能,對項目代碼幾乎無任何侵入性。

那麼咱們怎麼來使用這樣一個框架呢

一、在引用項右擊,選擇Nuget管理,這裏咱們要導入兩個包

一個是AutoFac包,另一個就是Autofac ASP.NET MVC5 Intergration

在webapi裏面使用的話咱們須要添加一個Autofac ASP.NET Web API2.2 Intergration 才能夠。

2.Global.asax.cs屬性注入,配置IOC容器,我這裏配置的是通用的以I開頭的Repository(倉庫類)

複製代碼
#region autofac IOC容器配置
            var builder = new ContainerBuilder();

            //註冊全部的controller
            builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
            //註冊全部模塊module
            builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());

            var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();

            //註冊全部繼承IDependency接口的類
            builder.RegisterAssemblyTypes(assemblys)
            .Where(type => typeof(IDependency).IsAssignableFrom(type) && !type.IsAbstract);

            //註冊服務,全部IxxxxRepository=>xxxxRepository
            builder.RegisterAssemblyTypes(assemblys).Where(t => t.Name.EndsWith("Repository") && !t.Name.StartsWith("I")).AsImplementedInterfaces();
          
            var container = builder.Build();

            BaseInfo._container = container;

            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
            #endregion
複製代碼

3.新建實體基類以及實體類,也就是建立數據模型

base類:

複製代碼
public class BaseEntity
    {
        [NotMapped]
        [PropertyModelBinder("start")]
        public int pageIndex { get; set; }

        [NotMapped]
        [PropertyModelBinder("length")]
        public int pageSize { get; set; }

        [NotMapped]
        public string draw { get; set; }

        [NotMapped]
        public List<Orderby> order { get; set; }

        [NotMapped]
        public List<Datacolumn> columns { get; set; }

    }


   public class Orderby {
       public string column { get; set; }

       public string dir { get; set; }
   }

 
   public class Datacolumn {
       public string data { get; set; }

       public string name { get; set; }

       public bool searchable { get; set; }

       public bool orderable { get; set; }
   }
複製代碼

實體類:

複製代碼
public class User : BaseEntity
    {
       public User() {
           RoleList = new List<Role>();
           MessageList = new List<UserMappingMessage>();
       }
       public int UserID { get; set; }

       public string UserName { get; set; }

       public string UserPassword {get;set;}

       public string UserReallyname {get;set;}

       public string HeadPortrait { get; set; }

       public string MobilePhone { get; set; }

       public string Email { get; set; }

       public int DepartmentID {get;set;}
        
       public bool IsEnable {get;set;}

       public DateTime CreateTime {get;set;}
       
       public DateTime? UpdateTime {get;set;}

       public string Remark { get; set; }

       public ICollection<Role> RoleList { get; set; }

       //接收消息列表
       public ICollection<UserMappingMessage> MessageList { get; set; }

       public Dictionary Department { get; set; }

       //發送消息列表
       public List<Message> Messages { get; set; }

    }
複製代碼

4.建立倉儲接口,由於我在配置Global屬性時,已經說明了我要注入全部以 「I」 開頭的接口,那麼我就把這個用戶的接口給定義爲IUserRepository

固然,不一樣的實體類所須要的倉儲接口也不同,這裏根據本身的實際需求去寫須要的方法類,接口嘛,就不要在這裏具體實現你的方法了

複製代碼
 public interface IUserRepository 
    {
        Tuple<int,List<User>> GetList(User model);

        List<User> GetUserInfos();

        User GetSingle(User model);

        User GetbyID(int userID);

        void AddUser(User model);

        void ModifyUser(User model);

        void DeleteUser(User model);

        void SetUserInfoRole(int userID, List<int> roleIDList);

        List<AutoUserDo> GetUserInfobyName(string value);

        void ResetUserPWDbyID(int id);

    }
複製代碼

5.咱們定義一個實現接口的類,而後把接口的方法給實現,這裏面就是對數據實體進行操做了

複製代碼
public class UserRepository : IUserRepository
    { 

        public Tuple<int, List<User>> GetList(User model)
        {
            using (UnitOfWork dal=BaseInfo._container.Resolve<UnitOfWork>())
            {
                var SysUserRepository = dal.GetRepository<User>();

                var conditions = ExpandHelper.True<User>();
                if (!string.IsNullOrEmpty(model.UserName))
                    conditions = conditions.And(a => a.UserName.Contains(model.UserName));

                if (!string.IsNullOrEmpty(model.UserReallyname))
                    conditions = conditions.And(a => a.UserReallyname.Contains(model.UserReallyname));

                if (model.DepartmentID > 0)
                    conditions = conditions.And(a => a.DepartmentID == model.DepartmentID);

                var templist = SysUserRepository.Get(filter: conditions, includeProperties: "RoleList");
         
                var count = templist.Count();

                if (model.order != null&&model.order.Count()>0)
                {
                    foreach (var item in model.order)
                    {
                        var column = model.columns.ElementAt(int.Parse(item.column));
                        templist = templist.OrderSort(column.data, item.dir);
                    }
                  
                }
                var result = templist.PageBy(model.pageIndex, model.pageSize).ToList();

                return new Tuple<int, List<User>>(count, result);
            }
        }

        public User GetSingle(User model)
        {
            using(UnitOfWork dal=BaseInfo._container.Resolve<UnitOfWork>()){

                var conditions = ExpandHelper.True<User>();

                if (!string.IsNullOrEmpty(model.UserName))
                    conditions = conditions.And( a => a.UserName == model.UserName || a.MobilePhone == model.UserName);
                if (!string.IsNullOrEmpty(model.MobilePhone))
                    conditions = conditions.And(a => a.MobilePhone == model.MobilePhone);


                var result = dal.GetRepository<User>().Get(conditions).FirstOrDefault();     
                return result;
            }
        }

        public User GetbyID(int userID)
        {
            using (UnitOfWork dal = BaseInfo._container.Resolve<UnitOfWork>())
            {
               
              //  var result = dal.GetRepository<User>().Get(filter: a => a.UserID == userID, includeProperties: "RoleList.MenuList,RoleList.rbList").AsNoTracking().FirstOrDefault();

                var result = dal.GetRepository<User>().Get(filter: a => a.UserID == userID,includeProperties: "RoleList").FirstOrDefault();

                foreach (var item in result.RoleList)
                {
                    var role=dal.GetRepository<Role>().Get(a=>a.RoleID==item.RoleID,includeProperties:"MenuList,rbList").FirstOrDefault();
                    item.MenuList = role.MenuList;
                    item.rbList = role.rbList;
                } 

                return result;
            }
        }
               
        public void AddUser(User model)
        {
            using (UnitOfWork dal = BaseInfo._container.Resolve<UnitOfWork>())
            {

                dal.GetRepository<User>().Insert(model);
                dal.Save();
            }
        }

        public void ModifyUser(User model)
        {
            using (UnitOfWork dal = BaseInfo._container.Resolve<UnitOfWork>())
            {
                dal.GetRepository<User>().UpdateSup(model, new List<string>() { "IsEnable", "CreateTime" }, false);
                dal.Save();
            }
        }

        public void DeleteUser(User model)
        {
            using (UnitOfWork dal = BaseInfo._container.Resolve<UnitOfWork>())
            {
               var sysUserRepository= dal.GetRepository<User>();
               var Usermodel = sysUserRepository.GetByID(model.UserID);
               Usermodel.IsEnable=Usermodel.IsEnable?false:true;
               sysUserRepository.UpdateSup(Usermodel, new List<string>() { "IsEnable" });
               dal.Save();
            }
        }

        /// <summary>
        /// 添加用戶角色信息,先刪除原有數據,在添加到數據庫
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="roleIDList"></param>
        /// <returns></returns>
        public void SetUserInfoRole(int userID, List<int> roleIDList)
        {
            using (UnitOfWork dal = BaseInfo._container.Resolve<UnitOfWork>())
            {
                var sysUserRepository = dal.GetRepository<User>();
                var roleRepository = dal.GetRepository<Role>();
                var UserModel = GetbyID(userID);
                var roleList = UserModel.RoleList.ToList();

                roleList.ForEach(m =>
                {
                    var userModel = sysUserRepository.Get(filter: a => a.UserID == userID, includeProperties: "RoleList").FirstOrDefault();
                    var roleModel = roleRepository.GetByID(m.RoleID);
                    userModel.RoleList.Remove(roleModel);
                });

                roleIDList.ForEach(m =>
                {
                    var userModel = sysUserRepository.GetByID(userID);
                    var roleModel = roleRepository.GetByID(m);
                    userModel.RoleList.Add(roleModel);
                });

                dal.Save();
            }         
        }


        public List<AutoUserDo> GetUserInfobyName(string value)
        {
            Mapper.Initialize(a =>
            {
                a.CreateMap<User, AutoUserDo>()
                 .ForMember(au => au.id, op => { op.MapFrom(user => user.UserID); })
                 .ForMember(au => au.text, op => { op.MapFrom(user => user.UserReallyname); })
                 .ForMember(au => au.department, op => { op.MapFrom(user => user.Department.DicValue); });
                a.CreateMap<Role, roleinfo>();
            });
            
            using (var dal = BaseInfo._container.Resolve<UnitOfWork>()) {

                return dal.GetRepository<User>()
                          .Get(a => a.UserReallyname.Contains(value) || a.MobilePhone == value, includeProperties: "Department,Role").ProjectToQueryable<AutoUserDo>().ToList();
                          
            }
        }


        public void ResetUserPWDbyID(int id)
        {
            using (var dal = BaseInfo._container.Resolve<UnitOfWork>())
            {

                var repository = dal.GetRepository<User>();
                var usermodel = new User()
                {
                    UserID = id,
                    UserPassword = "123456"
                };
                repository.UpdateSup(usermodel, new List<string>() { "UserPassword" });
                dal.Save();
            }
        }


        public List<User> GetUserInfos()
        {
            using (var dal = BaseInfo._container.Resolve<UnitOfWork>())
            {
                return dal.GetRepository<User>().Get().ToList();
            }
        }
    }
複製代碼

6.而後咱們就能夠在MVC的控制器裏面去調用這些方法來實現咱們所想要的功能了,我這裏只展現一個方法

複製代碼
public void SendEmailAsync(Message model)
        {
            Task.Run(() =>
            {
                try
                {
                    var reclist = string.Empty;
                    foreach (var item in model.RecUser.Split(','))
                    {
                        var userinfo = this.UserRepository.GetbyID(int.Parse(item));  //這裏就調用了實現接口的那個類的方法,去驗證用戶的ID
                        if (!string.IsNullOrEmpty(userinfo.Email))
                        {
                            reclist += userinfo.Email + ",";
                        }
                    }
                    if (!string.IsNullOrEmpty(reclist))
                    {
                        reclist = reclist.Substring(0, reclist.Length - 1);
                        EmailHelper email = new EmailHelper(reclist, model.MessageTitle, model.MessageText);
                        email.Send();
                    }
                    model.SendEmailState = 2;
                    this.MessageServer.SetSendState(model);
                }catch(Exception ex){
                    new LogHelper().LogError("發送郵件異常" + ex);
                    model.SendEmailState = 3;
                    this.MessageServer.SetSendState(model);    
                }
            });
        }
複製代碼

那麼整個流程就是這樣,看着別人寫的那些博客裏面的流程不是那麼的全面,我這裏就詳細的把AutoFac的整個流程給梳理出來了,有不對的地方請及時指出

後面我會詳細說明一下Unity IOC框架是如何使用的,這裏我就再也不敘述了

下面是兩篇比較好的博文,我以爲比較有參考意義的,能夠看一下,喜歡我發佈的內容的能夠關注我,後面還會有其餘的乾貨和內容進行分享

.NET領域最爲流行的IOC框架之一Autofac:https://www.cnblogs.com/yinrq/p/5381492.html

 .NET Unity IOC框架使用實例:https://blog.csdn.net/chen_peng7/article/details/54896449

 

C#特性詳解

 

特性(attribute)是被指定給某一聲明的一則附加的聲明性信息。

在C#中,有一個小的預約義特性集合。在學習如何創建咱們本身的定製特性(custom attributes)以前,咱們先來看看在咱們的代碼中如何使用預約義特性。

     

      

複製代碼
 1 using System;
 2 public class AnyClass
 3 {
 4     [Obsolete("Don't use Old method, use New method", true)]
 5     static void Old( ) { } 
 6     static void New( ) { }
 7     public static void Main( )
 8     {
 9         Old( );
10     }
11 }
複製代碼

 

  咱們先來看一下上面這個例子,在這個例子中咱們使用了Obsolete特性,它標記了一個不該該再被使用的程序實體。第一個參數是一個字符串,它解釋了爲何該實體是過期的以及應該用什麼實體來代替它。實際上,你能夠在這裏寫任何文本。第二個參數告訴編譯器應該把使用這個過期的程序實體看成一種錯誤。它的默認值是false,也就是說編譯器對此會產生一個警告。 

  當咱們嘗試編譯上面這段程序的時候,咱們將會獲得一個錯誤: 
  AnyClass.Old()' is obsolete: 'Don't use Old method, use New method' 


  開發定製特性(custom attributes) 

  如今讓咱們來看看如何開發咱們本身的特性。 
  首先咱們要從System.Attribute派生出咱們本身的特性類(一個從System.Attribute抽象類繼承而來的類,無論是直接仍是間接繼承,都會成爲一個特性類。特性類的聲明定義了一種能夠被放置在聲明之上新的特性)。

  1 using System; 2 public class HelpAttribute : Attribute 3 { 4 } 

  無論你是否相信,咱們已經創建了一個定製特性,如今咱們能夠用它來裝飾現有的類就好像上面咱們使用Obsolete attribute同樣。

 

  

1 [Help()]
2 public class AnyClass
3 {
4 }

 

  注意:對一個特性類名使用Attribute後綴是一個慣例。然而,當咱們把特性添加到一個程序實體,是否包括 Attribute後綴是咱們的自由。編譯器會首先在System.Attribute的派生類中查找被添加的特性類。若是沒有找到,那麼編譯器會添加 Attribute後綴繼續查找。 

    到目前爲止,這個特性尚未起到什麼做用。下面咱們來添加些東西給它使它更有用些。

 

複製代碼
 1 using System;
 2 public class HelpAttribute : Attribute
 3 {
 4     public HelpAttribute(String Descrition_in)
 5     {
 6         this.description = Description_in;
 7     }
 8     protected String description;
 9     public String Description
10     {
11         get
12         {
13             return this.description;
14         }
15     }
16 }
17 [Help("this is a do-nothing class")]
18 public class AnyClass
19 {
20 }
複製代碼

 

    在上面的例子中,咱們給HelpAttribute特性類添加了一個屬性而且在後續的部分中咱們會在運行時環境中查尋它。 

  定義或控制特性的使用 

  AttributeUsage類是另一個預約義特性類,它幫助咱們控制咱們本身的定製特性的使用。它描述了一個定製特性如和被使用。 
  AttributeUsage有三個屬性,咱們能夠把它放置在定製屬性前面。第一個屬性是: 


  ValidOn 
  經過這個屬性,咱們可以定義定製特性應該在何種程序實體前放置。一個屬性能夠被放置的全部程序實體在AttributeTargets enumerator中列出。經過OR操做咱們能夠把若干個AttributeTargets值組合起來。 


  AllowMultiple 
  這個屬性標記了咱們的定製特性可否被重複放置在同一個程序實體前屢次。 

  Inherited 
  咱們可使用這個屬性來控制定製特性的繼承規則。它標記了咱們的特性可否被繼承。 

  下面讓咱們來作一些實際的東西。咱們將會在剛纔的Help特性前放置AttributeUsage特性以期待在它的幫助下控制Help特性的使用。

 

複製代碼
複製代碼
 1 using System;
 2 [AttributeUsage(AttributeTargets.Class), AllowMultiple = false,
 3 Inherited = false ]
 4 public class HelpAttribute : Attribute
 5 {
 6     public HelpAttribute(String Description_in)
 7     {
 8         this.description = Description_in;
 9     }
10     protected String description;
11     public String Description
12     {
13         get
14         {
15             return this.description;
16         }
17     }
18 }
複製代碼

 

複製代碼

 

  先讓咱們來看一下AttributeTargets.Class。它規定了Help特性只能被放在class的前面。這也就意味着下面的代碼將會產生錯誤:

 

  

複製代碼
1 [Help("this is a do-nothing class")]
2 public class AnyClass
3 {
4     [Help("this is a do-nothing method")] //error
5     public void AnyMethod()
6     {
7     }
8 }
複製代碼

 

  編譯器報告錯誤以下:
  AnyClass.cs: Attribute 'Help' is not valid on this declaration type. 
  It is valid on 'class' declarations only.

 

  咱們可使用AttributeTargets.All來容許Help特性被放置在任何程序實體前。可能的值是: 

  Assembly,Module,Class,Struct,Enum,Constructor,Method,Property,Field,Event,Interface,Parameter,Delegate

    All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate

  ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface

  下面考慮一下AllowMultiple = false。它規定了特性不能被重複放置屢次。

 

複製代碼
1 [Help("this is a do-nothing class")]
2 [Help("it contains a do-nothing method")]
3 public class AnyClass
4 {
5     [Help("this is a do-nothing method")] //error
6     public void AnyMethod()
7     {
8     }
9 }
複製代碼

 

  它產生了一個編譯期錯誤。 
  AnyClass.cs: Duplicate 'Help' attribute 

  Ok,如今咱們來討論一下最後的這個屬性。Inherited, 代表當特性被放置在一個基類上時,它可否被派生類所繼承。

 

複製代碼
1 [Help("BaseClass")]
2 public class Base
3 {
4 }
5 public class Derive : Base
6 {
7 }
複製代碼

 

  這裏會有四種可能的組合: 

1 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false ]
2 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false ]
3 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true ]
4 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true ] 

 

  第一種狀況: 

  若是咱們查詢(Query)(稍後咱們會看到如何在運行期查詢一個類的特性)Derive類,咱們將會發現Help特性並不存在,由於inherited屬性被設置爲false。 

  第二種狀況: 

  和第一種狀況相同,由於inherited也被設置爲false。 

  第三種狀況: 

  爲了解釋第三種和第四種狀況,咱們先來給派生類添加點代碼: 

 

複製代碼
1 [Help("BaseClass")]
2 public class Base
3 {
4 }
5 [Help("DeriveClass")]
6 public class Derive : Base
7 {
8 }
複製代碼

 

  如今咱們來查詢一下Help特性,咱們只能獲得派生類的屬性,由於inherited被設置爲true,可是AllowMultiple卻被設置爲false。所以基類的Help特性被派生類Help特性覆蓋了。 

  第四種狀況: 

  在這裏,咱們將會發現派生類既有基類的Help特性,也有本身的Help特性,由於AllowMultiple被設置爲true。

 

    定義或控制特性的使用AttributeUsage類是另一個預約義特性類,它幫助咱們控制咱們本身的定製特性的使用。它描述了一個定製特性如何被使用。

 

屬性和特性的區別能夠參考一下: http://developer.51cto.com/art/200908/147097.htm

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/Foxalien/archive/2009/12/05/4946672.aspx

 

 

 

C#特性詳解

 

特性(attribute)是被指定給某一聲明的一則附加的聲明性信息。

在C#中,有一個小的預約義特性集合。在學習如何創建咱們本身的定製特性(custom attributes)以前,咱們先來看看在咱們的代碼中如何使用預約義特性。

     

      

複製代碼
 1 using System;
 2 public class AnyClass
 3 {
 4     [Obsolete("Don't use Old method, use New method", true)]
 5     static void Old( ) { } 
 6     static void New( ) { }
 7     public static void Main( )
 8     {
 9         Old( );
10     }
11 }
複製代碼

 

  咱們先來看一下上面這個例子,在這個例子中咱們使用了Obsolete特性,它標記了一個不該該再被使用的程序實體。第一個參數是一個字符串,它解釋了爲何該實體是過期的以及應該用什麼實體來代替它。實際上,你能夠在這裏寫任何文本。第二個參數告訴編譯器應該把使用這個過期的程序實體看成一種錯誤。它的默認值是false,也就是說編譯器對此會產生一個警告。 

  當咱們嘗試編譯上面這段程序的時候,咱們將會獲得一個錯誤: 
  AnyClass.Old()' is obsolete: 'Don't use Old method, use New method' 


  開發定製特性(custom attributes) 

  如今讓咱們來看看如何開發咱們本身的特性。 
  首先咱們要從System.Attribute派生出咱們本身的特性類(一個從System.Attribute抽象類繼承而來的類,無論是直接仍是間接繼承,都會成爲一個特性類。特性類的聲明定義了一種能夠被放置在聲明之上新的特性)。

  1 using System; 2 public class HelpAttribute : Attribute 3 { 4 } 

  無論你是否相信,咱們已經創建了一個定製特性,如今咱們能夠用它來裝飾現有的類就好像上面咱們使用Obsolete attribute同樣。

 

  

1 [Help()]
2 public class AnyClass
3 {
4 }

 

  注意:對一個特性類名使用Attribute後綴是一個慣例。然而,當咱們把特性添加到一個程序實體,是否包括 Attribute後綴是咱們的自由。編譯器會首先在System.Attribute的派生類中查找被添加的特性類。若是沒有找到,那麼編譯器會添加 Attribute後綴繼續查找。 

    到目前爲止,這個特性尚未起到什麼做用。下面咱們來添加些東西給它使它更有用些。

 

複製代碼
 1 using System;
 2 public class HelpAttribute : Attribute
 3 {
 4     public HelpAttribute(String Descrition_in)
 5     {
 6         this.description = Description_in;
 7     }
 8     protected String description;
 9     public String Description
10     {
11         get
12         {
13             return this.description;
14         }
15     }
16 }
17 [Help("this is a do-nothing class")]
18 public class AnyClass
19 {
20 }
複製代碼

 

    在上面的例子中,咱們給HelpAttribute特性類添加了一個屬性而且在後續的部分中咱們會在運行時環境中查尋它。 

  定義或控制特性的使用 

  AttributeUsage類是另一個預約義特性類,它幫助咱們控制咱們本身的定製特性的使用。它描述了一個定製特性如和被使用。 
  AttributeUsage有三個屬性,咱們能夠把它放置在定製屬性前面。第一個屬性是: 


  ValidOn 
  經過這個屬性,咱們可以定義定製特性應該在何種程序實體前放置。一個屬性能夠被放置的全部程序實體在AttributeTargets enumerator中列出。經過OR操做咱們能夠把若干個AttributeTargets值組合起來。 


  AllowMultiple 
  這個屬性標記了咱們的定製特性可否被重複放置在同一個程序實體前屢次。 

  Inherited 
  咱們可使用這個屬性來控制定製特性的繼承規則。它標記了咱們的特性可否被繼承。 

  下面讓咱們來作一些實際的東西。咱們將會在剛纔的Help特性前放置AttributeUsage特性以期待在它的幫助下控制Help特性的使用。

 

複製代碼
複製代碼
 1 using System;
 2 [AttributeUsage(AttributeTargets.Class), AllowMultiple = false,
 3 Inherited = false ]
 4 public class HelpAttribute : Attribute
 5 {
 6     public HelpAttribute(String Description_in)
 7     {
 8         this.description = Description_in;
 9     }
10     protected String description;
11     public String Description
12     {
13         get
14         {
15             return this.description;
16         }
17     }
18 }
複製代碼

 

複製代碼

 

  先讓咱們來看一下AttributeTargets.Class。它規定了Help特性只能被放在class的前面。這也就意味着下面的代碼將會產生錯誤:

 

  

複製代碼
1 [Help("this is a do-nothing class")]
2 public class AnyClass
3 {
4     [Help("this is a do-nothing method")] //error
5     public void AnyMethod()
6     {
7     }
8 }
複製代碼

 

  編譯器報告錯誤以下:
  AnyClass.cs: Attribute 'Help' is not valid on this declaration type. 
  It is valid on 'class' declarations only.

 

  咱們可使用AttributeTargets.All來容許Help特性被放置在任何程序實體前。可能的值是: 

  Assembly,Module,Class,Struct,Enum,Constructor,Method,Property,Field,Event,Interface,Parameter,Delegate

    All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate

  ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface

  下面考慮一下AllowMultiple = false。它規定了特性不能被重複放置屢次。

 

複製代碼
1 [Help("this is a do-nothing class")]
2 [Help("it contains a do-nothing method")]
3 public class AnyClass
4 {
5     [Help("this is a do-nothing method")] //error
6     public void AnyMethod()
7     {
8     }
9 }
複製代碼

 

  它產生了一個編譯期錯誤。 
  AnyClass.cs: Duplicate 'Help' attribute 

  Ok,如今咱們來討論一下最後的這個屬性。Inherited, 代表當特性被放置在一個基類上時,它可否被派生類所繼承。

 

複製代碼
1 [Help("BaseClass")]
2 public class Base
3 {
4 }
5 public class Derive : Base
6 {
7 }
複製代碼

 

  這裏會有四種可能的組合: 

1 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false ]
2 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false ]
3 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true ]
4 [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true ] 

 

  第一種狀況: 

  若是咱們查詢(Query)(稍後咱們會看到如何在運行期查詢一個類的特性)Derive類,咱們將會發現Help特性並不存在,由於inherited屬性被設置爲false。 

  第二種狀況: 

  和第一種狀況相同,由於inherited也被設置爲false。 

  第三種狀況: 

  爲了解釋第三種和第四種狀況,咱們先來給派生類添加點代碼: 

 

複製代碼
1 [Help("BaseClass")]
2 public class Base
3 {
4 }
5 [Help("DeriveClass")]
6 public class Derive : Base
7 {
8 }
複製代碼

 

  如今咱們來查詢一下Help特性,咱們只能獲得派生類的屬性,由於inherited被設置爲true,可是AllowMultiple卻被設置爲false。所以基類的Help特性被派生類Help特性覆蓋了。 

  第四種狀況: 

  在這裏,咱們將會發現派生類既有基類的Help特性,也有本身的Help特性,由於AllowMultiple被設置爲true。

 

    定義或控制特性的使用AttributeUsage類是另一個預約義特性類,它幫助咱們控制咱們本身的定製特性的使用。它描述了一個定製特性如何被使用。

 

屬性和特性的區別能夠參考一下: http://developer.51cto.com/art/200908/147097.htm

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/Foxalien/archive/2009/12/05/4946672.aspx

 

 

WPF 可觸摸移動的ScrollViewer控件

 

ListBox支持觸摸滑動,而ScrollViewer默認不支持。

ScrollViewer如須要添加上下/左右觸摸移動,須要在Touch事件中處理。

處理以下:封裝成一個用戶控件

  1. TouchDown事件中記錄起始點,並添加對TouchMove事件的監聽
  2. TouchUp事件中註銷TouchMove事件的監聽
  3. 在TouchMove事件中,處理移動的偏移量。起始位置減去偏移量,即爲當前滾動條的位置。

注:ScrollViewer滾動到指定位置(指定位置=起始位置-移動的偏移量,滾動方向和手勢方向相反)

複製代碼
 1     /// <summary>
 2     /// 可觸摸滾動的ScrollViewer控件
 3     /// </summary>
 4     public class TouchableScrollViewer : ScrollViewer
 5     {
 6         //觸摸點的座標
 7         Point _startPosition;
 8         //滾動條當前位置
 9         double _startVerticalOffset;
10         double _startHorizontalOffset;
11         public TouchableScrollViewer()
12         {
13             TouchDown += TouchableScrollViewer_TouchDown;
14 
15             TouchUp += TouchableScrollViewer_TouchUp;
16         }
17         private void TouchableScrollViewer_TouchDown(object sender, TouchEventArgs e)
18         {
19             //添加觸摸移動監聽
20             TouchMove -= TouchableScrollViewer_TouchMove;
21             TouchMove += TouchableScrollViewer_TouchMove;
22 
23             //獲取ScrollViewer滾動條當前位置
24             _startVerticalOffset = VerticalOffset;
25             _startHorizontalOffset = HorizontalOffset;
26 
27             //獲取相對於ScrollViewer的觸摸點位置
28             TouchPoint point = e.GetTouchPoint(this);
29             _startPosition = point.Position;
30         }
31 
32         private void TouchableScrollViewer_TouchUp(object sender, TouchEventArgs e)
33         {
34             //註銷觸摸移動監聽
35             TouchMove -= TouchableScrollViewer_TouchMove;
36         }
37 
38         private void TouchableScrollViewer_TouchMove(object sender, TouchEventArgs e)
39         {
40             //獲取相對於ScrollViewer的觸摸點位置
41             TouchPoint endPoint = e.GetTouchPoint(this);
42             //計算相對位置
43             double diffOffsetY = endPoint.Position.Y - _startPosition.Y;
44             double diffOffsetX = endPoint.Position.X - _startPosition.X;
45 
46             //ScrollViewer滾動到指定位置(指定位置=起始位置-移動的偏移量,滾動方向和手勢方向相反)
47             ScrollToVerticalOffset(_startVerticalOffset - diffOffsetY);
48             ScrollToHorizontalOffset(_startHorizontalOffset - diffOffsetX);
49         }
50     }
複製代碼

 Demo下載

提高能力,纔是王道
 

.NET(C#)能開發出什麼樣的APP?盤點那些經過Smobiler開發的移動應用

 

.NET程序員必定最熟悉所見即所得式開發,熟悉的Visual Studio開發界面,熟悉的C#代碼。

 

Smobiler也是由於具有這樣的特性,使開發人員,能夠在VisualStudio上,像開發WinForm同樣拖拉控件,讓許多人在開發APP時,再次回到所見即所得的開發方式中去。

Smobiler的快速開發,讓Amanda看到了程序員們分享的各式各樣的應用。

 

來自程序員的分享

 

👆產線物料管理類的應用

實時監控產線物料狀況

 

 

 

社區物業管理類的應用👇

方便社區居民在線查詢、繳費

 

 

 

👆公益社區類的應用

爲公益熱心者提供一個線上社區

 

 

 

企業內部OA管理應用👇

請假、工做流、報銷等功能

 

以上截圖均來自Smobiler技術開發羣用戶的分享

 

 

一千個應用有一千種界面

 

在「家庭小祕」沒出現以前,咱們也是想不到會有用戶願意在UI上投入資源,作出出這樣簡潔好看的界面。

 

家庭小祕APP

 

畢竟咱們見到更多的是企業類應用,對UI界面要求沒那麼高,功能至上。

 

好比這個花了十來天作的企業內部管理應用:

一款爲練手而作的APP

 

這只是練手之做,我們先把後端的業務代碼跑通,UI設計什麼的,正式項目裏,交給專業的設計師會更省事。

 

專業的和業餘雖然都能把意思表達出來,但區別就跟下面這張圖同樣:

 

 

官方推出的三款開源APP

 

Smobiler官方也前後推出了三款開源的應用,應用的源代碼已經託管至GitHub,這三款應用分別是

 

SmoONE:開源的移動OA應用

包含了GPS定位、IM等功能

 

SmoSEC:開源的資產管理移動應用

包含了條碼掃描、RFID掃描等功能

 

SmoWMS:開源的倉庫管理移動應用

包含倉庫管理中的基本核心功能,固然倉庫管理中的條碼掃描、RFID掃描等也是不可少的

(文末有這三款應用源代碼的獲取方式。)

 

重點是,這三款應用的代碼,都是

 

免費!開源的!

 

你能夠把源碼下載下來,而後根據項目的需求,進行二次開發。好比這樣

左圖是SmoONE的界面,右圖是用戶在SmoONE源碼基礎上的修改

 

好比這樣:

左圖是SmoWMS的界面,右圖是用戶在SmoWMS源碼基礎上的修改

 

 

這樣的界面從零作起,總共只分三步,大概須要兩分鐘吧

第一步:拖拉控件

 

 

第二步:設置title和toolbar屬性

 

第三步:設置iconmenuview屬性和啓動程序

 

最後作什麼樣的APP,徹底看項目須要,和程序員的心情,以及……客戶是否介意你依照本身的喜愛作出來的界面。

 

作項目嘛,最重要的是效率;敲代碼嘛,最重要的就是開心。

 

 

三款開源項目的獲取方式

 

在GitHub上搜索

「SmoONE」、「SmoSEC」、「SmoWMS」

即可找到。

 

也可複製如下地址至瀏覽器直接前往獲取。

 

SmoONE 移動OA應用

https://github.com/comsmobiler/SmoONE

包含了GPS定位、IM等功能

 

 

SmoSEC 資產管理移動應用

https://github.com/comsmobiler/SmoSEC

資產管理移動應用,包含了條碼掃描、RFID掃描等功能

 

 

SmoWMS 倉庫管理移動應用

https://github.com/comsmobiler/SmoWMS

包含倉庫管理中的基本核心功能,固然倉庫管理中的條碼掃描、RFID掃描等也是不可少的

 

 

.NET移動開發,關於發佈IOS的方法(本人親身經歷折騰好久終於成功)

 

前情提要:這位.NET程序員兄弟使用Smobiler開發了一個APP,儘管Smobiler雲平臺已經最大限度的簡化了iOS應用的打包操做,但仍繞不開蘋果公司強制要求的p12文件,p12文件須要開發者自行生成,在此,qio763分享了這次生成p12文件的經驗,不管是初學iOS原生開發,仍是.NET移動開發平臺的smobiler,在生成iOS安裝包以前,p12文件生成這一步都是必經之路

(P.S.提交了正確的p12文件後,應用已成功打包)

 

----------------------------------如下爲原文----------------------------------

 

在發佈IOS版本前,須要作的準備工做:
本人使用的虛擬主機,版本爲10.12(但不支持xcode10有點尷尬),若是你使用的MAC系統,能夠直接操做,虛擬主機方面請自行百度,此處不講

第一步,生成一個你的我的證書(鑰匙串)

 


第二步:進入IOS開發者中心進行相關的設置(此處很是重要,不少人包括我本人都出現了錯誤)


點擊Certificates下的all彈出的菜單中點擊+號,新添加一個你的我的證書,如已有證書可跳過此步


須要注意此步聚很重要,此處必須選擇紅框部分,由於smo發佈要求發佈正式版本,因此須要選擇此項,而後點擊continue直到出現如下畫面


點擊紅框部分,選擇剛纔咱們使用鑰匙串申請的文件


完成後點擊download下載到本地,雙擊剛下載的證書,將其導入到鑰匙串中

添加完成後,咱們須要將證書生成P12我的證書,這也是smo所須要的證書,咱們在鑰匙串中請行如下操做

右鍵點擊咱們剛纔添加的證書,選擇導出證書

導出證書時,文件格式默認爲P12,咱們就不要動了,也不要去管他,默認就好。

導出證書時需填寫一個你的導出密碼,這個密碼能夠隨意設置,但必須牢記,對應smobier中的導出密碼
到此,證書部分就算是完成了,企業證書原理同樣,操做方法也是這樣。下面是建立咱們的APPID與咱們的發佈描述。
發佈描述部分相對比較麻煩,不少用戶出錯基本都在這裏出錯(我本身在這出錯好幾回)

發佈描述,首先須要建立APPID

Identifiers》appids中點擊+號

須要注意的是BundleID必須與你的smobier的應用包名一致,若是不一致將沒法正常打包

 

必須勾選Push Notifications選項,包含了推送信息,而後點擊繼續按鈕直到完成

點擊剛建立的appid彈出詳細信息,咱們會發現,該功能並無應用,咱們點擊edit進行編輯



咱們會發現,關於Push Notifications部分有兩個選項,其實一個是測試版,一個是正式版,咱們這裏選擇正式版並建立,點擊繼續按鈕進入選擇頁面


點擊選擇按鈕,咱們選擇,咱們最開始用鑰匙串生成的文件,點擊繼續完成appid Push Notifications的修改,至此,appid建立完成,接下來就是發佈描述文件的生成了


Provisioning Profiles→Distribution

點擊Distribution中的+號



在此處咱們選擇正式版,也就是紅色框部分,點擊繼續



此處選擇,咱們剛纔建立的appid,此ID對應的是咱們的smobiler的包名



選擇咱們第一步建立的證書,點擊繼續,完成發佈描述,點擊download下載咱們的發佈描述文件


咱們在smobiler的應用平臺發佈IOS時,就將咱們剛纔生成的P12文件上傳,密碼填寫咱們導出P12證書的密碼,將下載的發佈描述文件上傳後,就能夠完成IOS的打包了


打包IOS很重要,特別是你的插件,若是包名錯誤了,再刪除是很難恢復的,個人插件就是由於打包操做出現問題就沒有了,很難過

 

做者:qio763

(原帖地址:https://www.smobiler.com/forum.php?mod=viewthread&tid=11605

相關文章
相關標籤/搜索