武漢肺炎衝擊小龍蝦出口中國 紐西蘭准有條件放生

摘錄自2020年2月6日聯合新聞網報導

武漢肺炎疫情持續延燒,現在也衝擊到紐西蘭對中國大陸出口市場。因中方經銷商取消大筆訂單,高達150至180公噸的小龍蝦被困在養殖容器內、動彈不得。紐國政府已表示,將允許出口商有條件放生,讓小龍蝦重回大海。

中國農曆新年向來是小龍蝦消費的高峰期,但武漢肺炎爆發後,民眾對紐西蘭小龍蝦的需求下降,中方因此取消價值達3.2億紐幣(折合約台幣62億元)的訂單。

紐西蘭漁業部長奈許(Stuart Nash)聲明表示,允許放生代表貿易恢復正常後,可以再度捕撈這些小龍蝦,但考慮到小龍蝦來源不同,因此並非所有等候出口的小龍蝦都能回到大海。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

土耳其東部連續兩日雪崩 最少38人死

摘錄自2020年2月6日星島日報報導

土耳其東部連續第二日發生雪崩,導致最少38人死亡,多人被活埋。

事發在當地周二(4日)晚,鄰近伊朗邊境的東部邊境凡省的山區發生雪崩,當時一架剷雪車及一架小巴被埋,造成至少五人死亡,兩人失蹤。當局派出300名救援人員周三中午到場尋找失蹤者,卻遭遇第二次雪崩。

當局指事件合共有38人喪生,多人被活埋。當中包括軍人、警察、消防員和志願者。另外有53人受傷,仍有多人被埋在雪下。當地政府指已救出25個被埋的救援人員,但無交代他們的情況。目前仍有超過50人可能被困,警告死傷人數可能增加。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

CSS(6)—浮動(float)

CSS(6)—通俗講解浮動(float)

CSS有三模塊:盒子模型浮動定位。上篇博客有講到 盒子模型地址:

一、理解浮動

1、概念

概念 浮動可以理解為讓某個div元素脫離標準流,漂浮在標準流之上,和標準流不是一個層次。

如果是第一次聽說肯定還是還是一臉懵,下面我一步一步通過例子來解釋這句話。

舉例說明

我們知道div是塊級元素,在頁面中獨佔一行,自上而下排列,也就是傳說中的標準流

如下圖

可以看出,因為div是塊級元素,所以即使div2的寬度很小,頁面中一行可以容下div2和div3,div3也不會排在div2後邊,因為div元素是獨佔一行的。

那麼我們再看下浮動的作用,這裏我將div2浮動(對div2添加float:left;左浮動屬性)

刷新頁面

通過上下兩張圖片對比,我們可以直觀感覺到,div2有種浮起來的感覺,從之前的平面到立體的感覺。也因為div2浮起來了,那麼它之前所佔的位置也就空出來了,

那麼div3和div4就可以佔據之前div2的位置,所以它們都往上移動了。這樣我們最終看到的效果就是div2和div3,div4有重疊,而且div2是在最上層。

那如果這是我在把div3也設置左浮動呢 (對div3添加float:left;左浮動屬性)

再次刷新頁面

同樣我們可以很直觀的看到,因為div2和div3目前都是左浮動,所以它們的位置都空出來了,這個時候div4就可以往上移動,所以div2和div3都把div4部分給覆蓋了。

通過上面示例,我們應該可以理解什麼是浮動。這裏附上上面示例的代碼,可以自行再研究下

<!DOCTYPE html>
<html> 
<head>
    <title>css浮動</title>
    <style type="text/css">
        div {
           text-align: center;
        }
        .one {
            background-color: gray;
            width: 300px;
            height: 50px;
        }
        .two {
            background-color: yellow;
            width: 100px;
            height: 120px;
            /*float:left;*/
        }
        .three {
            background-color: red;
            width: 150px;
            height: 50px;
            /*float:left;*/ 
        }

        .four {
            background-color: green;
            width: 300px;
            height: 50px;
        }
    </style>
</head>

<body>
    <div class="one"> div1</div>
    <div class="two"> div2</div>
    <div class="three">div3 </div>
    <div class="four"> div4</div>
</body>
</html>

通過上面也可以得出一些結論:

1、假如某個div元素A是浮動的,如果A元素上一個元素也是浮動的,那麼A元素會跟隨在上一個元素的後邊(如果一行放不下這兩個元素,那麼A元素會被擠到下一行);

2、如果A元素上一個元素是標準流中的元素,那麼A的相對垂直位置不會改變,也就是說A的頂部總是和上一個元素的底部對齊。

2、浮動的作用

浮動它主要有兩個作用:1、實現文本圍繞效果2、實現塊級元素在一行显示布局

1)實現文本圍繞效果

示例

<!DOCTYPE html>
<html> 
<head>
    <title>css浮動</title>
    <style type="text/css">
        .father {
            border: 3px solid #005588;
            padding: 1px;
           width: 300px;
        }
        img {
            width: 150px; 
            height: 150px;
            float:left;
        }
    </style>
</head>

<body>
<div class = "father">
    <img src="1.jpeg"/>
    這件衣服價值百萬,奢侈品牌是指服務於奢侈品的品牌。它是品牌等級分類中的最高等級品牌。在生活當中,奢侈品牌享有很特殊的市場和很高的社會地位。在商品分類里,與奢侈品相對應的是大眾商品。奢侈品不僅是提供使用價值的商品,更是提供高附加值的商品。
</div> 
</body>
</html>

運行結果

2)實現塊級元素在一行显示布局

現在很多時候會通過浮動,讓多個div實現一行显示。當然當我們沒有了解浮動之前我們可以通過將塊級元素轉換為行內塊級元素來實現(display: inline-block)。

如圖

這樣確實可以將多個div實現在同一行显示。但這裡會有兩個小問題

 1、我們可以看到div之前會有小縫隙,很難去除。
 2、如果我想讓其中一個div显示在最右邊,實現起來會比較麻煩。

而上面兩個問題可以通過浮動很輕易的解決。

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>cssdiv元素局一行</title>
    <style>
    div {
        display: inline-block;
        width: 120px;
        height: 80px;
        /*float: left;*/
    }
    .one {
        background-color: pink;
    }
    .two {
        background-color: purple;
    }
    .three {
        background-color: red;
            /*float: right;*/
    }
    </style>
</head>
<body>
    <div class="one">div1</div>
    <div class="two">div2</div>
    <div class="three">div3</div>
</body>
</html>

運行結果

很明顯已經解決。

二、浮動語法

1、浮動的語法

在 CSS 中,我們通過 float 屬性實現元素的浮動。float 屬性定義元素在哪個方向浮動。

基本語法格式

選擇器 {float:屬性值;}

屬性值

2、浮動特性

浮動脫離標準流,不佔位置,會影響標準流。浮動只有左右浮動。

注意 浮動的元素總是找理它最近的父級元素對齊。但是不會超出內邊距的範圍。

如圖

浮動特性

1、浮動脫離標準流,不佔位置,會影響標準流。浮動只有左右浮動。
2、加了浮動的元素盒子是浮起來的,漂浮在其他的標準流盒子上面。
3、加了浮動的盒子,不佔位置的,它浮起來了,它原來的位置會給後面標準流的盒子。
4、一個父盒子裏面的子盒子,如果其中一個子級有浮動的,則其他子級都需要浮動。這樣才能一行對齊显示。
5、元素添加浮動后,元素會具有行內塊元素的特性。元素的大小完全取決於定義的大小或者默認的內容多少浮動根據元素書寫的位置來显示相應的浮動。
6、假如在一行之上只有極少的空間可供浮動元素,那麼這個元素會跳至下一行,這個過程會持續到某一行擁有足夠的空間為止。

總結 浮動的目更多的是為了讓多個塊級元素同一行上显示。

參考

1、

2、

3、

4、

你如果願意有所作為,就必須有始有終。(8)

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

Go組件學習——Web框架Gin

以前學Java的時候,和Spring全家桶打好關係就行了,從Spring、Spring MVC到SpringBoot,一脈相承。

對於一個Web項目,使用Spring MVC,就可以基於MVC的思想開發項目了,不管是應對前後端分離還是不分離的場景,你都可以輕鬆駕馭。因為你只要知道,你用的是一個Web開發框架就行了。

相比於Spring在Java一家獨大的局面,Go生態中的Web框架還在百家爭鳴的階段。從今天開始學習一款基於Go語言開發的Web開發框架Gin。

簡介

Github:https://github.com/gin-gonic/gin

語言:Go語言

官網:https://gin-gonic.com/

 

環境搭建

Go版本:1.12.4

系統:macOS

依賴管理工具:go mod

IDE:Goland

因為我使用了go mod,所以引用gin的依賴算是很方便了。

如何創建一個go mod管理的新項目以及如何將老項目改造為go mod,可以參見這篇文章:https://juejin.im/post/5c8e503a6fb9a070d878184a,寫的很詳細了。

這就是我的go-demo:https://github.com/DMinerJackie/go-demo項目的所有第三方依賴了。

那麼如何添加gin的依賴呢?有以下三種方式

  • 直接新建一個基於gin的example程序文件,然後執行 go build xxx.go或者 go run xxx.go命令,go mod就會自動幫你下載gin依賴並更新go.mod文件。

  • 同上,還是新建一個example程序文件,然後在項目根目錄下執行 go mod tidy命令,go mod會幫你安排上。這個命令可以幫助你移除不需要的依賴,並拉取引用你需要的依賴。

  • 在go.mod文件中手動添加依賴類似 github.com/gin-gonic/gin v1.4.0這種。

幾乎不用什麼繁瑣的步驟,就完成了環境搭建。下面開始寫第一個基於Gin的demo

 

第一個Demo

1、新建文件helloworld.go

package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() // 監聽並在 0.0.0.0:8080 上啟動服務
}

  

2、點擊執行該程序

從控制台程序可以看出服務已經啟動,並且開始監聽8080端口

3、訪問接口

接下來我們在瀏覽器輸入localhost:8080/ping即可看到程序返回的結果

一個極簡的Web服務器就這樣搭建完成並對外訪問了。

上面的代碼中

通過 r:=gin.Default()聲明一個gin的引擎,後續的操作都是基於這個引擎的。

通過 r.GET申明一個可以訪問的路由,定義的HTTP請求方式為GET請求。同時定義了請求后對應的處理方式,即一個閉包函數聲明以JSON格式返回的鍵值對。

通過 r.Run()監聽指定端口並啟動服務

 

其他Demo

1、渲染HTML

雖然現在很多都倡導並實行前後端分離了,即後端只提供HTTP接口,前端負責調用HTTP接口以及頁面渲染。

但還是有前後端揉在一起的使用場景,gin就提供了這種能力。

具體的做法是提供一個HTML模板,服務端將得到的數據填充到模板中實現頁面的渲染。

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	router := gin.Default()
	router.LoadHTMLGlob("main/src/gin-example/examples/templates/**/*")
	router.GET("/posts/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title": "Posts",
		})
	})
	router.GET("/users/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
			"title": "Users",
		})
	})
	router.Run(":8080")
}

  

index.tmpl

{{ define "posts/index.tmpl" }}
<html><h1>
	{{ .title }}
</h1>
<p>Using posts/index.tmpl</p>
</html>
{{ end }}

  

user.tmpl

{{ define "users/index.tmpl" }}
<html><h1>
	{{ .title }}
</h1>
<p>Using users/index.tmpl</p>
</html>
{{ end }}

  

對應的HTML模板文件目錄結構如下

代碼部分

router.LoadHTMLGlob用於指明HTML模板文件的路徑

router.GET同上,定義訪問路由和返回結果,不同於第一個Demo的是,這裡有賦值填充的過程,比如

c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
			"title": "Posts",
		})

  

將index.tmpl中定義的 .title替換為”Posts”

執行結果如下

2、PureJSON

func main() {
	r := gin.Default()
	
	// 提供 unicode 實體
	r.GET("/json", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"html": "<b>Hello, 世界!</b>",
		})
	})
	
	// 提供字面字符
	r.GET("/purejson", func(c *gin.Context) {
		c.PureJSON(200, gin.H{
			"html": "<b>Hello, 世界!</b>",
		})
	})
	
	// 監聽並在 0.0.0.0:8080 上啟動服務
	r.Run(":8080")
}

  

這裏兩個GET方法唯一不同的就是要渲染的內容一個使用JSON()方法一個使用PureJSON()方法。

啟動程序后,我們看下訪問結果有什麼不同

可以看出JSON()渲染的會有中文以及標籤轉為unicode編碼,但是使用PureJSON()渲染就是原樣輸出(我的瀏覽器裝了插件,會自動解碼,所以不點擊右邊的”RAW“兩個接口返回的結果是一樣的)。

這個問題,本周我們服務端在和客戶端對接的時候還遇到了,因為框架返回的JSON串就是經過編碼的,但是單獨請求放到瀏覽器是沒有問題的,客戶端收到的卻是經過編碼的,最後排查發現是瀏覽器插件解碼了。

3、渲染多種數據交換格式的數據

gin支持渲染XML、JSON、YAML和ProtoBuf等多種數據格式

import (
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/testdata/protoexample"
	"net/http"
)

func main() {
	r := gin.Default()

	// gin.H 是 map[string]interface{} 的一種快捷方式
	r.GET("/someJSON", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
	})

	r.GET("/moreJSON", func(c *gin.Context) {
		// 你也可以使用一個結構體
		var msg struct {
			Name    string `json:"user"`
			Message string
			Number  int
		}
		msg.Name = "Lena"
		msg.Message = "hey"
		msg.Number = 123
		// 注意 msg.Name 在 JSON 中變成了 "user"
		// 將輸出:{"user": "Lena", "Message": "hey", "Number": 123}
		c.JSON(http.StatusOK, msg)
	})

	r.GET("/someXML", func(c *gin.Context) {
		c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
	})

	r.GET("/someYAML", func(c *gin.Context) {
		c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
	})

	r.GET("/someProtoBuf", func(c *gin.Context) {
		reps := []int64{int64(1), int64(2)}
		label := "test"
		// protobuf 的具體定義寫在 testdata/protoexample 文件中。
		data := &protoexample.Test{
			Label: &label,
			Reps:  reps,
		}
		// 請注意,數據在響應中變為二進制數據
		// 將輸出被 protoexample.Test protobuf 序列化了的數據
		c.ProtoBuf(http.StatusOK, data)
	})

	// 監聽並在 0.0.0.0:8080 上啟動服務
	r.Run(":8080")
}

  

今天先到這,後面再看看gin的源碼。

 

如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!如果您想持續關注我的文章,請掃描二維碼,關注JackieZheng的微信公眾號,我會將我的文章推送給您,並和您一起分享我日常閱讀過的優質文章。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

Asp.net Core 系列之–4.事務、日誌及錯誤處理

ChuanGoing 2019-11-17

    這篇原本想把事務處理、日誌處理、錯誤處理、授權與鑒權一併介紹完的,授權和鑒權我想結合自定義權限來介紹,全部放到這裏篇幅可能太長,因此權限部分將會在下篇來介紹。先說下我接下來的打算把,下篇將介紹權限控制,結合Oauth2.0和OpenId(OIDC)以及自定義權限來介紹;完了後會結合之前所介紹的基礎來實現一個簡單的電商網站,當然是利用領域驅動設計來實現。我的這個系列的主題就是領域驅動設計,實現簡單電商網站時將會深入的講解下領域的劃分原則及領域服務的場景,中間可能會嘗試部分業務實現事件驅動。

本篇學習曲線:

1.日誌記錄

2.錯誤處理

3.事務處理

日誌記錄

    NLog是一個記錄日誌組件,和log4net一樣被廣泛使用,它可以將日誌保存到文本文件、CSV、控制台、VS調試窗口、數據庫等。在之前例子中的WebApi項目中添加NLog.Web.AspNetCore的Nuget包,並添加如下配置:

 

 

   簡單介紹下配置信息,“targets”配置每個輸出配置,我這裡有3個輸出:database、allfile、ownfile,分別表示輸出到數據庫和對應路徑的日誌文件下。

“rules”規則配置了4條:

1.將Debug以上級別(含)信息輸出到allfile

2.忽略Microsoft.*開頭的信息(對應的輸出沒有配置到任何文件),此配置一般忽略即可

3.將Debug以上級別(含)信息輸出到ownfile(注意這裏配置和allfile一樣,一般配置級別高點的日誌信息)

4.將Warn以上級別(含)信息輸出到數據庫

完了后,在Program.cs Main方法裏面註冊NLog:

var logger = NLogBuilder.ConfigureNLog($"Nlog.config").GetCurrentClassLogger();
            try
            {
                CreateWebHostBuilder(args).Build().Run();
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Stopped program because of exception");
                throw ex;
            }
            finally
            {
                NLog.LogManager.Shutdown();
            }

注意不要忘了啟用NLog組件使之生效

 

在OrderController的Add方法中加入以下代碼:

 

用postman簡單測試下,我們可以看到執行目錄中多出來了日誌信息

 

 

錯誤處理

  這裏一般我們關心的錯誤大概有兩類:

1.內部錯誤,即通過框架(Mvc)管道準確的傳入到內部系統中併發生錯誤的此類信息

2.框架(Mvc)執行管道的某些中間件時發生的錯誤或被中間件禁止繼續訪問的請求

  因此,定義如下3個類:

public class InnerException : Exception
    {
        /// <summary>
        /// 內部錯誤代碼
        /// </summary>
        public int? ErrorCode { get; }

        public InnerException(int errorCode) : base()
        {
            ErrorCode = errorCode;
        }

        public InnerException(int errorCode, string message) : base(message)
        {
            ErrorCode = errorCode;
        }

        public InnerException(int code, string message, Exception exception) : base(message, exception)
        {
            ErrorCode = code;
        }
    }

InnerException

public class MessageCodes
    {
        #region 公用

        /// <summary>
        /// 成功
        /// </summary>
        public const int Success = 20101000;
        /// <summary>
        /// 警告
        /// </summary>
        public const int Warning = 20102000;
        /// <summary>
        /// 錯誤
        /// </summary>
        public const int Error = 20103000;
        /// <summary>
        /// 數據驗證錯誤
        /// </summary>
        public const int DataValidationError = 20104000;
        /// <summary>
        /// 數據不存在
        /// </summary>
        public const int DataNotFound = 20105000;
        /// <summary>
        /// 非法的數據狀態
        /// </summary>
        public const int IllegalState = 20106000;
        /// <summary>
        /// 參數無效
        /// </summary>
        public const int InvalidParams = 20107000;
        /// <summary>
        /// 輸入非法
        /// </summary>
        public const int IllegalInput = 20108000;
        /// <summary>
        /// 鑒權成功
        /// </summary>
        public const int AuthSuccess = 20109000;

        #endregion

    }

MessageCodes

 public class WebException: InnerException
    {
        public HttpStatusCode HttpStatus { get; set; }

        public HttpRequest Request { get; private set; }

        public WebException(HttpStatusCode httpStatus, int errorCode, string message)
             : base(errorCode, message)
        {
            HttpStatus = httpStatus;
        }

        public WebException(HttpStatusCode httpStatus, int errorCode, string message, HttpRequest request)
            : this(httpStatus, errorCode, message)
        {
            Request = request;
        }

        public WebException(int errorCode, string message)
            : base(errorCode, message)
        {
            HttpStatus = HttpStatusCode.BadRequest;
        }
    }

WebException

通過Aop,很方便就可以實現錯誤信息的處理:

public class ExceptionFilter : IExceptionFilter
    {
        private readonly ILogger<ExceptionFilter> _logger;

        public ExceptionFilter(ILogger<ExceptionFilter> logger)
        {
            _logger = logger;
        }

        public void OnException(ExceptionContext context)
        {
            _logger.LogError(context.Exception, context.Exception.Message);

            #region Ioc/automapper等中間件對錯誤信息進行了包裝,需要解包

            //web錯誤:驗證/鑒權等
            var webException = GetException<Base.Exceptions.WebException>(context.Exception);
            if (webException != null)
            {
                context.Result = new JsonResult(new
                {
                    ErrorCode = webException.ErrorCode ?? MessageCodes.Error,
                    webException.Message
                })
                {
                    StatusCode = (int)webException.HttpStatus
                };
                return;
            }
            //內部錯誤
            var exception = GetException<InnerException>(context.Exception);
            if (exception != null)
            {
                context.Result = new JsonResult(new
                {
                    ErrorCode = exception.ErrorCode ?? MessageCodes.Error,
                    exception.Message
                })
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError
                };
                return;
            }

            #endregion
        }

        private TException GetException<TException>(Exception exception)
          where TException : Exception
        {
            if (exception == null)
            {
                return null;
            }
            if (exception is TException tException)
            {
                return tException;
            }
            else
            {
                return GetException<TException>(exception.InnerException);
            }
        }
    }

ExceptionFilter

同時,Startup.cs的ConfigureServices中註冊一下:

services.AddMvc(mvcOptions =>
                {
                    mvcOptions.Filters.Add<ExceptionFilter>();
                })

即完成了錯誤信息並且錯誤信息會寫入相應配置的輸出中。

事務處理

  UnitOfWork又稱工作單元,為了保證數據操作完整性,我們將處理數據的的操作統一放在一個事務中,我們這裏利用UnitOfWork來實現事務處理。

首先定義IUnitOfWork及UnitOfWork實現:

 public interface IUnitOfWork
    {
        void Begin(IsolationLevel level = IsolationLevel.Unspecified);
        void SaveChanges();
        void Failed();
    }

View Code

public class UnitOfWork : IUnitOfWork
    {
        private ITransactionRepository _repository;

        public UnitOfWork(ITransactionRepository repository)
        {
            _repository = repository;
        }

        public virtual void Begin(IsolationLevel level = IsolationLevel.Unspecified)
        {
            _repository.BeginTransaction(level);
        }

        public virtual void SaveChanges()
        {
            _repository.Commit();
        }

        public virtual void Failed()
        {
            _repository.Rollback();
        }
    }

View Code

其中,UnitOfWork依賴於ITransactionRepository的實現:

public interface ITransactionRepository
    {
        /// <summary>
        /// 打開事務
        /// </summary>
        /// <param name="level"></param>
        void BeginTransaction(IsolationLevel level = IsolationLevel.Unspecified);
        /// <summary>
        /// 提交事務
        /// </summary>
        void Commit();
        /// <summary>
        /// 事務回滾
        /// </summary>
        void Rollback();
    }

ITransactionRepository

利用DapperRepository繼承ITransactionRepository並實現:

public virtual void BeginTransaction(IsolationLevel level = IsolationLevel.Unspecified)
        {
            DbContext.BeginTransaction(level);
        }

        public virtual void Commit()
        {
            DbContext.Commit();
        }

        public virtual void Rollback()
        {
            DbContext.RollBack();
        }

View Code

基本功能實現后,如何使用呢?這裏還是需要利用Aop:

public class UnitOfWorkAttribute : AbstractInterceptorAttribute
    {
        public override Task Invoke(AspectContext context, AspectDelegate next)
        {
            if (context.Implementation is IApplicationService applicationService)
            {
                var uow = applicationService.UnitOfWork;
                uow.Begin();
                var aspectDelegate = next(context);
                if (aspectDelegate.Exception != null)
                {
                    uow.Failed();
                    throw aspectDelegate.Exception;
                }
                else
                {
                    uow.SaveChanges();
                    return aspectDelegate;
                }
            }
            else
            {
                return next(context);
            }
        }
    }

UnitOfWorkAttribute

因此,我們還需要在Application項目中添加如下代碼:

 public class ServiceBase<TEntity, TPrimaryKey> : IApplicationService
        where TEntity : class, IEntity<TPrimaryKey>
    {
        protected IMapper Mapper { get; private set; }
        public virtual IUnitOfWork UnitOfWork { get; private set; }

        public ServiceBase(IComponentContext container, ICommandRepository<TEntity, TPrimaryKey> repository)
        {
            Mapper = container.Resolve<IMapper>();
            UnitOfWork = container.Resolve<IUnitOfWork>(new TypedParameter(typeof(ITransactionRepository), repository));
        }
    }

ServiceBase

Application中的每個服務去繼承上面的ServiceBase,因此每個Application服務都具有了事務處理能力

 public interface IOrderService : IScopeInstance
    {
        [UnitOfWork]
        void Add(OrderViewModel order);
        OrderViewResult Get(string sn);
    }

 

 程序運行時,Add方法前後形成切面,如下圖所示,next(context)這裏執行的就是Add方法,執行前開啟事務,執行后提交

 

 利用Aop特性切面實現事務的無感注入(Ioc/DI小節中引入了AspectCore動態代理),底層還是依賴IDbConnection的事務相關接口,完整的事務處理大概就是這樣了。

詳細代碼在Github的 的Domain分支可以找到。

 

 

    

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

雪梨30年最大雨 熄了野火又迎水災

摘錄自2020年2月11日聯合新聞網報導

暴雨10日襲擊澳洲雪梨和新南威爾斯州東岸,是雪梨30年來最大降雨,澳洲當局因此發佈緊急撤離令。這場雨澆熄了自去年十一月開始肆虐的野火,同時給澳洲最大城市雪梨帶來混亂。

澳洲氣象局表示,過去四天內,雪梨降下391.6毫米雨量,到處淹水且交通打結,河水氾濫,超過60間學校關閉,數千人被迫撤離家園,上萬人無電可用。

澳洲氣象局警告,暴雨可能導致新南威爾斯州南岸山洪爆發,並表示可能會有超過每小時90公里的強風。新南威爾斯州鄉村消防局10日表示,大雨澆熄了該州最嚴重的野火火場,這場大火延燒74天,摧毀300多間房舍,燒毀50萬公頃土地。

農夫對降雨表示歡迎,但也認為一場大雨不足以解決三年的乾旱。乾旱和極端氣候,導致澳洲東南部自去年九月以來野火肆虐,造成至少33人死亡,約十億野生動物喪命,2,500多間房舍和1,170萬公頃土地被燒毀。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

暖化效應 美國冬麥種植量劇減

摘錄自2020年2月10日聯合新聞網報導

由於天候暖化導致美國中西部春季種植季節雨量過多、土壤過度濕潤,讓冬麥播種困難,種植量因而降至逾一世紀以來最低,可能衝擊蘇打餅、Oreo等餅乾的原料供應。

軟紅冬麥受到的衝擊尤深,在伊利諾等重要種植州的播種已銳減25%。去年創紀錄的降雨曾導致美國農民的播種步調創有史以來最慢,甚至放棄「雙期作」策略,也就是在同一塊農地於春季播種黃豆、秋季播種小麥的做法。收成時間延至秋季,但秋季是農民向來希望進行冬麥播種的時節。這些農民選擇放棄栽種小麥,氣候型態變遷正破壞全世界傳統農耕時序。

一些測量結果顯示,美國正處於70年來第二溫暖的冬天。栽種減少並非是唯一威脅,因為美國天候愈來愈溫暖與潮濕,可能有利於真菌在6月收成季展開之前增加繁殖。去年真菌問題導致農作物品質降低,品質良好、能用於製作食品的農產品價格因而上漲。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

蘋果電動車核心人物離職 計畫受挫

蘋果為發展電動車計畫,四處挖角人才;如今核心人員Steve Zadesky被爆即將離職,外界認為這將使蘋果電動車計畫受到不小的損失。

Zadesky在蘋果公司任職已超過15年,曾參與過iPhone、iPad等明星產品研發,也開發過許多蘋果的專利。他從2014年起開始帶領蘋果電動車團隊,並從各大車廠延攬人才;對Tesla的挖角更曾讓Elon Musk發下「全世界都知道蘋果在坐電動車」、「(Tesla)東西夠好就不怕(競爭)」等豪語。

根據聯合財經網所整理的綜合外電資料,Zadesky的離職將影響到目前尚未成熟的蘋果電動車產品;但也有人認為,蘋果的資金充足,應該能找到很多適合帶領計畫的人選。

而有消息人士透漏,蘋果電動車相關的自動駕駛車團隊遇到了一些計畫目標上的麻煩,計畫的實際發展與公司的要求之間出現了落差。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

LG電子將為一汽提供電池組等電動汽車核心配件

據《朝鮮日報》報導,LG電子與一汽成功簽訂合作合同,將為一汽提供電池組、變流器和推動器等電動車核心配件。

LG電子提供的電池組能夠儲存電動汽車所需的動力,變流器能夠把電池的直流電轉換成交流電,推動器則是發動機等各種動力裝置。

LG之前曾與東風和吉利兩家中國車企簽署配件供應合同。LG沒有公開具體供應細節,但可以看出在電動車市場急劇增長的中國市場取得了不少成果。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

特斯拉香港熱賣 Model X正式進港

電動車品牌特斯拉(Tesla)首度公佈香港銷售成績。旗下房車Model S的2015年交付量高達2,221輛,不只勝過其他廠牌電動車,更是去年全香港銷售量最好的私家車款。Tesla加碼搶攻香港市場,已宣布多功能汽車Model X將正式進港,最快於2016年下半年開始交車。

香港政府統計,截至去年年底,全港共有4,198輛電動車掛牌行駛,比2014年底時的1,551量增加了接近三倍。其中,Tesla全年銷量2,221輛,占全港電動車總銷售量84%,穩坐冠軍寶座。為此,Elon Musk日前正式宣佈Model X將「進港」,當地售價約在90萬港幣左右。

香港蘋果日報報導,Musk認為香港電動車市場仍有很大成長空間。目前香港仍有99%的汽車是傳統的汽油車,還需幾年時間才能讓電動車成為主流車輛。不過,Model X的反應仍然不錯,已預訂的香港市民最快能在2016年後半年交車。為拓展香港市場,Tesla已在香港設置75個專用充電站,包含10個「超級充電站」,是全世界超級充電站密度最高的地方;Tesla未來仍將繼續增建充電設備與汽車維修中心。

Musk也讚賞香港是電動車基礎建設相當完善的城市,可以作為其他城市的榜樣。

同為Tesla,中港兩樣情

Tesla Model S在香港銷售開紅盤,但在中國卻差強人意。而根據香港蘋果日報的報導,Musk認為這樣的現象主要出自於兩地政府的支持力道差別。其中一例是進口稅,在中國銷售Tesla的進口稅極高,使得中國地區的Tesla售價遠高於其他地區,也連帶壓抑銷售量。

Tesla已開始評估是否在中國設立電動車生產工廠,但目前尚無具體定案。Musk本人也坦承,低油價確實衝擊到電動車的市場,且中國主要電力來自燃煤,使得吃電的電動車其實並沒有看起來那麼「環保」。若風電、太陽能等再生能源在中國電力結構中佔比增加,才能提升電動車的環保價值。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!