Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58
将json转成class在线工具 http://json2csharp.com/
将json转成class在线工具 http://json2csharp.com/
1,简单点,将程序放在共享中,从共享访问。缺点是在更新时需要程序都通出才能覆盖。
2,升级,用microsot提供的clickonce技术,自动更新,缺点是有限制
3,用通用组件 AutoUpdater.NET
node-webkit开发桌面应用 :将html打包成exe运行,好处一客户不用单独再安装chrome,,浏览器设置可封装,比如刷新缓存这些
是用c++写成,可直接访问本地资源,界面可以加菜单。
WebKit负责HTML5 UI 相关的部分,而Node.js负责本地的API接口,比如文件系统,网络,设备等。
使用:编辑package.json 放在nw根目录下,用enigma virtual box打包使用
作者相关:http://www.csdn.net/article/2014-01-08/2818066-Node-Webkit
清除缓存:C:UsersgoodasongAppDataLocalLvShou,lvshou是指在package.json指定的name
中文文档
用Enigma Virtual打包时,dll选择:
nw.pak:必需,是javascript库
icudtl.dat:必需,是网络库
ffmpegsumo.dll:媒体库,比如作用video这些需有此dll支持
libEGL.dll:webgl使用
libGLESv2.dll:gpu使用
d3dcompiler_47.dll:调试webgl使用
pdf.dll
Enigma Virtual Box:将多个文件如dll,exe打包成一个文件直接可以运行,可以写注册表
遇到的问题:
系统要使用flash,而显示的效果是有些电脑flash显示正常,有些却不能。
通过阅读wiki知,需要增加”plugin”: true,默认是不加载插件的,此解决一,但还是会有flash不显示的电脑,
在package.json所在目录增加plugins,里面放入flash插件NPSWF32_11_8_800_168.dll,所有电脑都可显示flash。
原因:是在”plugin”: true后,NW会去系统目录找flash插件,因电脑安装原因,可能flash插件不能固定的地方,然后它会去package.josn所在的plugins中查找,就是我们放plugins目录的的所在。
package.json:
{
“main”: “http://xxxxx.xx/login.aspx” ,
“name”: “LvShou”,
“version”: “0.1”,
“window”: {
“title”: “微商管理系统V3.0 Powered By asong”,
“toolbar”: false,
“frame”: true,
“width”: 1024,
“height”: 768,
“position”: “center”,
“resizable”: true,
“icon”: “key.png”,
“show”: true
},
“webkit”: {
“plugin”: true
}
}
https://github.com/nwjs/nw.js/wiki/Third-party-browser-plugins
在bin下,若对其添加到TFS,则项目成员在生成时回相互签出,操作不便,而若掩蔽Bin文件,则.refresh文件则也被掩蔽,若添加新的引用,就不能让项目组其他成员获取。
解决方法,有TFS提供的掩蔽文件,指定哪些不添加进tfs,若dll
方法:
自动生成.tfignore文件
在 *** 挂起的更改 *** 页上,在 *** 排除的更改 *** 部分中,选择 *** 检测更改 *** 链接。
*** 提升候选更改 *** 出现对话框。
选择文件,打开其快捷菜单,并选择 *** 忽略此本地项目 ***、*** 通过扩展忽略 ***或 *** 由文件名忽略 ***。
选择 *** 好 *** 或 *** 取消 *** 关闭 *** 提升候选更改 *** 对话框。
.tfignore文件显示在 *** 挂起的更改 *** 页的 *** 包含的更改 *** 部分。 可以打开此文件并修改它以满足您的需要。
.tfignore文件自动添加为包含挂起的更改,以便您创建的规则将应用于获取文件的每个团队成员。
参考:向服务器添加文件 http://msdn.microsoft.com/library/vstudio/ms245454(v=vs.110).aspx#tfignore
1,通过浏览添加的DLL,会在bin下面生成一对应人.refresh文件,里面有存位置
2,通过添加整个项目方式,会在.sln文件中保存此配置
3,通过添加.net已有程序集的方式,会在web.config中有记录。
Visual Studio Website Reference Paths
http://stackoverflow.com/questions/279451/visual-studio-website-reference-paths
为文件生成指纹,可以比较文件是否篡改。
C# 计算文件的MD5值:http://www.cnblogs.com/anjou/archive/2008/08/05/1261290.html
上ngix做负载均衡,ngix可以据IP固定一台服务器访问,这样可解决session共享问题,不过,还是单独一台服务器存session好一些,可以放到缓存或者服务中。
1,在web.config中配置:
2,在指定服务器172.16.88.88中开启远程访问
vs2012已经提供了发布功能,可以直接ftp上传,但ftp上传是对每个文件上传,若网速比较慢,就时间比较长。这里提供命令行发布,然后进行压缩操作。
@echo off set fdir=%WINDIR%\Microsoft.NET\Framework64 if not exist %fdir% ( set fdir=%WINDIR%\Microsoft.NET\Framework ) set msbuild=%fdir%\v4.0.30319\msbuild.exe %msbuild% website.publishproj /p:DeployOnBuild=true /p:PublishProfile=.\App_Data\PublishProfiles\发布.pubxml /p:VisualStudioVersion=11.0 /p:OutputPath=M:\deploy rd /s /q M:\deploy\images rd /s /q M:\deploy\Files del M:\deploy\web.config del M:\deploy\login.aspx rename M:\deploy\login3.aspx login.aspx "C:\Program Files\WinRAR\rar.exe" a -ag -k -r -s -ibck M:\s6release\s6_.rar M:\deploy start M:\s6release
winrar.exe:运行winrar,
如果winrar.exe没在默认路径中则需要指明路径,如c:\Progra~1\winrar\winrar.exe …;
a :备份所有文件;
-ag :当创建压缩文件时,以格式“YYYYMMDDHHMMSS”附加当前日期字符串,文件名bakYYYYMMDDHHMMSS.rar;
-k :锁定压缩文件;
-r:备份目录和子目录;
-s :创建固实压缩文件;
-ibck :后台运行;
M:\s6release\s6_.rar :备份的路径和基本名称(-ag参数会自动在bak后加上系统当前时间),
也可不用-ag参数,通过“%date:~0,4%%date:~5,2%%date:~8,2%”取得时间字串,
也可写作c:\bak.zip;
M:\deploy :要备份的文件目录。
restful:表现层状态传输
1,返回的结果格式由客户端的Content-Type指定,即表现多变
2,对应的方法是get,post.GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
3,mvc webapi对应:建立的方法由[[HttpPost]]指定关联
引用:理解RESTful架构 ASP.NET Web API(一):使用初探,GET和POST数据
控制ASP.NET Web API 调用频率
ASP.NET Web API 接口执行时间监控
可以用chrome提供的插件来进行构造测试
Postman – REST Client
大数据下的可视化工具,绝对强大,可以动态展示很多数据,图形不固定,图形可以是矢量的
https://github.com/mbostock/d3/wiki/Gallery
node.js可以用在并发量特别高而业务逻辑比较简单的场合中。
当我把Node.js介绍给人们的时候,通常会产生两种反应。总的来说人们不是可以正确的理解它,就是被搞得非常糊涂。
如果你到目前为止还处于第二组里,下面是我想要用来讲解node的内容:
“但是我可以做任何我想要做的事情用:ruby,python,php,java, … !”
我听到了你的声音。你是对的。Node不是该死的独角兽,它不会帮你做你自己的工作,抱歉。它只是一个工具,并且它大概也不会完全地替换你常用的工具,至少当前不会。
“说重点!”
好的,我会的。Node总的来说非常优秀当你需要同时做许多事情的时候。你有过写了一部分代码然后说“我想要这个并行执行”吗?好吧,在node中任何东西都是并行运行的,除了你的代码。
“嘿?”
是的没错,任何东西都是并行的,除了你的代码。为了理解它,把你的代码想像成是国王,然后node是它的仆从军队。
新的一天以仆从叫醒国王并且问他是否需要什么而开始了。国王给了这个仆从一个任务列表,然后回去继续睡觉去了(汗)。这个仆从把这些任务分配给了他的同僚,然后他们开始工作。
当一个仆从完成了一个任务,他会在国王领地外边排成一条线来汇报。国王一次让一个仆从进来,然后听取他的报告。有时候国王会在仆从出去的时候给仆从更多的任务。
生活是美好的,因为国王的仆从并行的执行他的任务,但是一次只报告一个结果,所以国王可以专注。*
“那是异想天开,但是你能结束这个愚蠢的比喻并且用geek的方式告诉我吗?”
当然。一个简单的node程序看起来可能是这样的:
1
2
3
4
5
6
7
8
9
10
11
|
<code> var fs = require( 'fs' ) , sys = require( 'sys' ); fs.readFile( 'treasure-chamber-report.txt' , function (report) { sys.puts( "oh, look at all my money: " +report); }); fs.writeFile( 'letter-to-princess.txt' , '...' , function () { sys.puts( "can't wait to hear back from her!" ); }); </code> |
你的代码给了node两个任务用来读写一个文件,然后就休眠了。当node完成了一个任务,跟它对应的回调就会被触发。但是在同一时间只能有一个回调触发。在那个回调完成了执行之前,所有其他的回调不得不排队等待。进一步说,对于回调触发的顺序是无法保证的。
“所以我不必担心代码在同一时间访问同一个数据结构?”
你理解了!这就是JavaScript的单进程/事件循环设计的全部美之所在。
“非常好,但是为什么我应该用它?”
一个原因是效率。在一个web应用中,你主要的响应时间消耗通常是执行数据库查询的时间之和。通过node,你可以一次执行你所有的查询,把响应时间减少为执行最慢查询所花费的时间。
另一个原因是JavaScript。你可以使用node来在浏览器和你的后端之间共享代码。JavaScript也正在变成一个真的通用语言。不管过去你用的是python,ruby,java,php或者其他语言,你都可能用过一些JS,对吗?
最后一个原因是原始速度。V8时刻在向成为全球最快的动态语言解释器之一而努力。我想不到任何其他语言在速度上有像如今的JavaScript一样有如此突飞猛进的提升。进一步说,node的I/O能力非常轻量级,可以使你可以尽可能的完全利用你系统完全的I/O能力。
“所以你在说我应该从现在起用node来写我所有的应用?”
是和不是。一旦你开始抡node这个锤子,那么显然一切开始看起来都像一个钉子。但是如果你当前的工作有一个期限,你可以通过以下来决定:
“node能运行在Windows上吗?”
不行。如果你使用的是windows,你需要运行一个Linux虚拟机(我推荐VirtualBox)。node对Windows的支持在计划中了,但是接下来的几个月不要屏住呼吸除非你想对port提供帮助。(译者:现在node可以完美的运行在Windows上)
“我能在node中访问DOM吗?”
好问题!不行,DOM是浏览器中的东东,并且node的JS引擎(V8)幸好跟那些混乱的东西是完全分离的。不过,有人在以node模块的形式来实现DOM,可能带来令人兴奋的可能性比如对客户端代码进行单元测试。
“难道事件驱动编程不是真的非常难吗?”
这取决于你。如果你已经学过如何在浏览器中摆弄AJAX调用和用户事件,那么使用node不会是一个问题。
同时,测试驱动开发可以真正的帮助你以一个可维护的设计做为开始。
“谁在用它?”
在node wiki(滚动到”Companies using Node”)有一个小的/不全的列表。Yahoo正在为YUI对node进行实验,Plurk正在使用它处理大规模的comet,并且Paul Bakaus(由于jQuery UI而出名)正在创建一个令人兴奋的游戏引擎,其中后端使用了一些node代码。Joyent已经雇佣了Ryan Dahl(node作者)并且大力资助开发。
对了,Heroku也刚刚声明了支持对node.js的托管。
“我能去哪里学更多?”
Tim Caswell正在运作优秀的How To Node博客。在twitter上Follow #nodejs。订阅邮件列表。然后去IRC频道逛逛,#node.js(是的,名字中包含这个点)。我们在那的划艇分数快达到200了:)。
我也将会继续在debuggable.com这里写文章。
当前就写这么多了。如果你有其他问题欢迎留言。
引自:理解 Node.js
在测试过程中,被测试的功能并不总是很简单,可能这个功能块有多个逻辑组成,如其中一个逻辑A是要查询数据库返回一个列表,那么在编写测试方法时就不得不考虑连接数据库的事情,并且,若数据库发生更改的话,做的测试也需要相应的更改。此时利用fake来假冒逻辑A即可,即是将逻辑A查询数据库的方法做一委托,用自定义的代码返回值即可,这就实现了与数据库的无关性。
Stub:接口模拟
Shim:具体方法模拟
在测试时
1要引入 Microsoft.QualityTools.Testing.Fakes;
2,要在模拟上下文中操作,只有这样类用到有模拟的方法才会自动调用我们所实现的
using (ShimsContext.Create())
Microsoft Fakes 可以提供成员模拟的方法.以方便进行单元测试
如果不使用模拟方法我们要关心很多东西,如数据库的数据变化,接口调用导致的变化,文件、及其它资源的访问等问题。
使用模拟我们则可以只关系我们需要测试的那部分逻辑。
Microsoft Fakes 提供了两种模拟类型成员的方式.以下两种方式的替代实现,都可以由委托来重新实现.
1.Stub Type,存根类型,可以动态地为接口及非密封的virtual或属性附加委托,以重新定义其实现,生成的类为强类型.
2.Shim Types,填充类型,解决了密封类或static成员的问题,T的填充类型ShimT可以为T的每个成员提供一个替代实现
由于Stub和Shim的实现方式不同,所以它们也有不同的要求,下面总结了选择它们的一些原则:
性能方面:运行时使用Shim重写会影响性能,Stub由于使用的是虚方法,则无此问题
对static方法/sealed类型:Stub类型只可以重写虚方法,因此,它不适用于static方法/sealed方法/sealed类中的方法,等
Internal类型:对于标记了InternalsVisibleToAttribute的内部类型,Fakes也可以起作用
private方法:如果private方法的签名上的所有类型都是可见类型,那么可以通过Shim来替换实现.Stub只能替换可见方法.
接口和抽象方法:Stub可以提供接口或抽象方法的替代实现.Shim则不能,因为没有实际的方法体.
所以建议在一般情况下使用Stub来支持那些可测试性做的非常好的类型,而用Shim来解决那些耦合很大,可测试性很差的代码或三方组件.
假设我们在项目ClassLibrary1中有以下几个类
1: public interface IDataAccess
2: {
3: int Read();
4: }
5:
6: public class MyDataAccess : IDataAccess
7: {
8: public int Read()
9: {
10: return Tools.GetNum();
11: }
12: }
13:
14: public class Tools
15: {
16: static public int GetNum()
17: {
18: return 1;
19: }
20: }
21:
22: public class MyClass
23: {
24: public static int GetMyData(IDataAccess obj)
25: {
26: //其它逻辑
27: return obj.Read();
28: }
29: }
我们要使用Fakes进行测试只需要在测试项目中引用 ClassLibrary1,并且在之上右键->建立 Fakes即可使用Fakes
之后我们就可以使用类似以下代码来模拟一个IDataAccess的实例 ,MyClass.GetMyData 这个static方法的实现
前者即使用Stub,后者即Shim
1: [TestClass]
2: public class UnitTest1
3: {
4: [TestMethod]
5: public void StubTest()
6: {
7: IDataAccess stockFeed = new ClassLibrary1.Fakes.StubIDataAccess()
8: {
9: Read = () => { return 2; }
10: };
11: Assert.AreEqual(2, MyClass.GetMyData(stockFeed));
12:
13: }
14: [TestMethod]
15: public void ShimTest()
16: {
17: using (ShimsContext.Create())
18: {
19: ClassLibrary1.Fakes.ShimMyClass.GetMyDataIDataAccess = (inc) => { return 2; };
20: Assert.AreEqual(2, MyClass.GetMyData(null));
21: }
22:
23: }
24:
25: }
Stub 与其它Mock差不多,只是使用委托来改变方法实现
而Shim则需要建立 ShimsContext的作用域
可参考:
1. 确保没有任何警告(warnings)。
2.如果先执行Code Analysis(启用所有Microsoft Rules)再消除所有警告就更好了。
3. 去掉所有没有用到的usings。编码过程中去掉多余代码是个好习惯。(参考:msdn)
4. 在合理的地方检查对象是否为’null’,避免运行的时候出现Null Reference Exception。
5. 始终遵循命名规范。一般而言变量参数使用驼峰命名法,方法名和类名使用Pascal命名法。(参考:msdn)
6. 请确保你了解SOLID原则。
根据维基百科定义:在程序设计领域,SOLID (单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期引入的记忆术首字母缩略字,指代了面向对象编程和面向对象设计的五个基本原则。当这些原则被一起应用时,它们使得一个程序员开发一个容易进行软件维护和扩展的系统变得更加可能。SOLID所包含的原则是通过引发编程者进行软件源代码的代码重构进行软件的代码异味清扫,从而使得软件清晰可读以及可扩展时可以应用的指南。SOLID被典型的应用在测试驱动开发上,并且是敏捷开发以及自适应软件开发的基本原则的重要组成部分。参考:wiki/SOLID_(面向对象设计)
7. 代码可重用性:如果一块代码已经被使用超过一次,或者你希望将来使用它,请提取成一个方法。将重复的工作做成通用的方法放在相关的类中,这样一旦你完成别人就可以使用了。将常用功能开发成用户控件,这样可以跨项目重用它们。(参考:① 、 ②)
8. 代码一致性:比方说,Int32写成int,String写成string,应该在代码里保持统一形式。不能一会二写成int一会儿写成Int32。
9. 代码可读性:代码应该是可维护的,便于其他开发者理解。(参考:msdn)
10. 释放非托管资源,比如文件I/O,网络资源等。一旦使用结束就应该释放它们。如果你想一旦超出使用范围就自动释放对象,可以使用usings将非托管代码括起来。参考:msdn
11. 合理实现异常处理(try/catch和finally块)和异常记录。参考:msdn
12. 确保代码中方法的行数不要过多,不超过30到40行。
13. 及时用代码管理工具check-in/check-out代码。(比如TFS) 参考:codeproject.com
14. 相互审查代码:和你的同事交换代码,实现内部审查。
15. 单元测试:编写开发测试用例完成单元测试,确保代码被送到QA以前,基本测试完成。参考:msdn
16. 尽量避免for/foreach循环嵌套和if条件嵌套。
17. 如果代码只会使用一次,请使用匿名类型。参考:msdn
18. 尽量使用LINQ查询和Lambda表达式,增加可读性。参考:msdn
19. 合理使用var、object和dynamic关键字。由于很多开发者会感到困惑或者知道的很少,会觉得它们有些相似,故而交换使用,这是要避免的。参考:blogs.msdn
20. 使用访问限定符(private, public, protected, internal, protected internal)限定每个方法、类或变量的需要范围。比方说如果一个类只会在程序集内使用,那么定义成internal就足够了。参考:msdn
21. 在需要保持解耦的地方使用接口,有些设计模式的出现也是由于接口的使用。参考:msdn
22. 按照用法和需要将类定义为sealed、static或abstract。参考:msdn
23. 如果需要多次串联,请使用Stringbuilder代替string,这可以节省堆内存。
24. 检查是否有不可能执行的代码,如果有,请修改。
25. 在每个方法前注释,说明它的用法、输入类型和返回值类型信息。
26. 使用类似Silverlight Spy的工具,检查和操控Silverlight应用在运行时对XMAL的渲染,以此来改善效率。这可以在设计执行XAML时,节省大量退回和来回修改的时间。
27. 使用filddler工具通过检查HTTP/网络流量和带宽,来跟踪web应用和服务的性能。
28. 如果你想确认Visual Studio以外的方法,请使用WCFTestClient.exe工具,或者装载它的进程到Visual Studio来进行调试。
29. 在任何合理的地方使用constants和readonly。参考:/msdn、msdn
30. 尽量避免强制转换和类型转换,因为会造成性能损失。参考:msdn
31. 对于你想提供自定义信息的类,请重载ToString(来自Object类)。参考:msdn
32. 避免直接从其他代码中ctrl+c/ctrl+v。一直建议还是自己用手敲,即使你已经找到相关代码。这样可以锻炼自己写代码能力,还能正确理解那段代码的用法。最终你永远都不会忘记那段代码。
33. 保持阅读书籍和文章的良好习惯,遵循大神们的实践指导。(比如微软专家和一些著名的专家,Martin Fowler, Kent Beck, Jeffrey Ritcher, Ward Cunningham, Scott Hanselman, Scott Guthrie, Donald E Knuth.)
34. 确认代码是否有内存泄漏。如果有,请确保已修正。参考:blogs.msdn.com
35. 尽可能参加专家们组织的技术研讨会,可以接触到最新的软件趋势、技术和最佳实践
36. 要透彻理解OOP概念,并尽可能在代码里实现。
37. 知道项目设计架构,可以从整体上理解程序的执行流程。
38. 采取必要措施阻止避免任何交叉脚本攻击、SQL注入和其他安全漏洞。
39. 永远记得将保密和敏感信息加密(通过使用好的加密算法),比如保存到数据库的密码和保存在web.config文件中的连接字符,要避免被非认证的用户操纵。
40. 避免对已知类型(原始类型)使用默认关键字,比如int, decimal, bool等。多数情况下,如果不确定是值类型还是引用类型,就使用泛型类型(T)。参考:msdn
41. 微软(在代码分析条例和指导中)并不推荐使用’out’和’ref’,这些关键字是通过引用传参,请注意,’ref’参数在传入被调用方法之前,应当在调用方法中先初始化,但’out’参数就不是这样。参考:msdn
mongodb和memcached不是一个范畴内的东西。mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据。mongodb和memcached不存在谁替换谁的问题。
和memcached更为接近的是redis。它们都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存。在我们团队的项目中,一开始用的是memcached,后来用redis替代。
相比memcached:
1、redis具有持久化机制,可以定期将内存中的数据持久化到硬盘上。
2、redis具备binlog功能,可以将所有操作写入日志,当redis出现故障,可依照binlog进行数据恢复。
3、redis支持virtual memory,可以限定内存使用大小,当数据超过阈值,则通过类似LRU的算法把内存中的最不常用数据保存到硬盘的页面文件中。
4、redis原生支持的数据类型更多,使用的想象空间更大。
5、前面有位朋友所提及的一致性哈希,用在redis的sharding中,一般是在负载非常高需要水平扩展时使用。我们还没有用到这方面的功能,一般的项目,单机足够支撑并发了。redis 3.0将推出cluster,功能更加强大。
6、redis更多优点,请移步官方网站查询。
算法原理
1)将长网址md5生成32位签名串,分为4段, 每段8个字节;
2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略处理;
3)这30位分成6段, 每5位的数字作为字母表的索引取得特定字符, 依次进行获得6位字符串;
4)总的md5串可以获得4个6位串; 取里面的任意一个就可作为这个长url的短url地址;
算法描述:使用6个字符来表示短链接,我们使用ASCII字符中的'a'-'z','0'-'5',共计32个字符做为集合。每个字符有32种状态,六个字符就可以表示32^6(1073741824),那么如何得到这六个字符,描述如下:
对传入的长URL进行Md5,得到一个32位的字符串,这个字符串变化很多,是16的32次方,基本上可以保证唯一性。将这32位分成四份,每一份8个字符,这时机率变成了16的8次方,是4294967296,这个数字碰撞的机率也比较小啦,关键是后面的一次处理。我们将这个8位的字符认为是16进制整数,也就是1*('0x'.$val),然后取0-30位,每5个一组,算出他的整数值,然后映射到我们准备的32个字符中,最后就能够得到一个6位的短链接地址。
参考:
1、.NET 框架支持两种程序集:强命名程序集(strongly named assembly)和非强命名程序集。
强命名程序集有一个发布者的公钥/私钥对签名,其中的公钥/私钥对唯一地标识了程序集的发布者。利用公钥/私钥对我们可以对程序集进行唯一的标识、安全策略和版本策略。(由于简单地用文件名导致了目前所谓的DLL Hell,强命名程序集就是CLR用来唯一地标识一个程序集的机制。)
2、一个程序集有两种部署方式:私有方式和全局方式。
非强命名程序集只能进行私有部署。
全局部署方式将程序集部署在一些CLR确知的地方,当CLR搜索程序集时,它会知道到这些地方去查找。强命名程序集既可以进行私有部署,也可以进行全局部署。它提供多个应用程序域访问同一个程序集的能力,特别地,内存中只存在该程序集的同一份副本,这种非特定于域的代码共享极大节省了内存资源占用。并且,在大多数情况下,共享程序集安装在全局程序集高速缓冲存储器(Global Assembly Cache)中而不存在于应用程序相关目录下,对它的引用不会产生文件复制,自然也不会产生额外的副本。因而,共享程序集不能简单通过XCOPY命令实现部署,而应使用MSI(Microsoft Windows Installer)进行。当组件和主应用程序不由同一个开发商建立,或者一个大应用程序分布在几个小工程中时,常常需要使用共享程序集。
3,引用流程: 如果文件名包含了完整路径,则 CSC.exe 加载指定路径下的文件。如果指定的是不带路径的文件,它将在以下目录中查找引用的程序集:
a、当前工作路径;
b、编译器目前使用的CLR所在的目录。MSCorLib.dll总是包含在该目录中(System.Object就定义在这个程序集中)。该目录类似于:
C:/Windows/Micorsoft.NET/Framework/v1.0.3427 ;
c、任何用CSC.exe的 /lib 命令行开关指定的目录;
d、任何LIB环境变量中指定的目录
安装.NET框架时,微软的程序集文件会被分别拷贝到 CLR所在目录及 GAC目录中。在CLR所在目录中拷贝是使我们能够方便的生成自己的程序集;GAC中的拷贝则是用于运行时加载这些程序集。
CSC.exe 不在GAC 中查找所引用的程序集的原因是因为需要指定的路径比较麻烦。
4,可用vs自带的合成日志查看器查看程序集加载过程
5,创建与部署:用SN工具生成强签名,用GACUti部署到全局,这样一个程序集可被多个应用程序访问
一、实现IHttpModule类,见后。 二、修改web.config 添加域名 <appSettings><add key="RootDomain" value=""/></appSettings> RootDomain cookie域名,若是本地则写空 by design domain names must have at least two dots otherwise browser will say they are invalid when working on localhost (!) the cookie-domain must be set to "" or NULL or FALSE instead of "localhost" 增加过滤 <system.web> <sessionState mode="StateServer" stateNetworkTimeout="10" timeout="120" stateConnectionString="tcpip=127.0.0.1:42424" /> <httpModules> <add name="SessionSharedHttpModule" type="ClassLibrary.BasePage.MakeSessionIDOneOnly,ClassLibrary"/> </httpModules> </system.web> 三、附类 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; using System.Reflection; using System.Configuration; namespace ClassLibrary.BasePage { public class MakeSessionIDOneOnly : IHttpModule { private string m_RootDomain = string.Empty; #region IHttpModule Members public void Dispose() { } public void Init(HttpApplication context) { m_RootDomain = ConfigurationManager.AppSettings["RootDomain"]; Type stateServerSessionProvider = typeof(HttpSessionState).Assembly.GetType("System.Web.SessionState.OutOfProcSessionStateStore"); FieldInfo uriField = stateServerSessionProvider.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic); if (uriField == null) throw new ArgumentException("UriField was not found"); uriField.SetValue(null, m_RootDomain); context.EndRequest += new System.EventHandler(context_EndRequest); } void context_EndRequest(object sender, System.EventArgs e) { HttpApplication app = sender as HttpApplication; for (int i = 0; i < app.Context.Response.Cookies.Count; i++) { if (app.Context.Response.Cookies[i].Name == "ASP.NET_SessionId") { app.Context.Response.Cookies[i].Domain = m_RootDomain; } } } #endregion } }