在学习中,总是以功能实现为目的,不善于总结,不求甚解,这导致我盲点愈积愈多,知识面得不到很好的扩展。因此,当看到一些新的技术很难以理解,也由于错误的观点将其置之于门外。现在,我要准备行动了!
好了,废话不多说,下面就开始迈出我的第一步吧!
反正据我所知,许多人在学了很长一段时间之后,居然还分不清C#与.NET,下面就针对这个问题,说一下我的理解。
.NET:一般指.NET Framework框架,是一种平台,一种技术。
C#:一种编程语言,可以开发基于.NET平台的应用。
那么我们学习.NET可以做什么呢?大致有以下几种:
1、桌面应用程序
2、Internet应用程序
3、手机开发
.NET到底是什么东东呢?
一般来说.NET Framework包括.NET Framework类库和CLR(公共语言运行时,common language runtime)
.NET Framework类库又包括:
1、ASP.NET(web窗体,webservice),Winform
2、ADO.NET和XML类
3、基本框架类
CLR(公共语言运行时)又包括:
1、CLS:公共语言规范
2、CTS:通用类型系统
3、JIT:即时编译器
C#和.NET到底有什么关系呢?
我们用C#写的源代码文件首先经过csc.exe(C#编译器)编译为IL(微软中间语言),然后在程序运行时把IL交由CLR(上面提到了)编译为可由计算机直接执行的机器码。
这样做有什么好处呢?
跨平台性(大多是还是微软自己的平台,汗。。。),跨语言性
由各种.NET支持的语言编写的程序都可以被其相对应的编译器编译为IL,然后我们将此程序集在任何安装了.NET Framework平台的系统上运行,都可以由CLR编译为与本机相关的机器码。另外CLR编译时还有一个特点是就是即时编译(Just In Time)
好了,关于C#与.NET Framework的关系就说到这,由于本人还是菜鸟(甚至连菜鸟都算不上),难免会有出错的地方,还望大家多多指教。
InfoQ上有一篇文章是 使用IAPIExplorer列举ASP.NET Web API,文章针对的版本是ASP.NET Web API Beta版本写,IAPIExplorer已经包含在RC版本里了,而且发现ASP.NET Web API的HttpConfiguration 的RC版本比Beta版本多了一个属性:
public DefaultServices Services { get; internal set; }
Debug进去可以看到默认有18个服务,IAPIExplorer 就是其中之一:
使用该API可以完成的工作有:
- 产生文档
- 创建机器可读的元数据
- 创建一个测试客户端
微软员工Yao发表了两篇文章(ASP.NET Web API: Introducing IApiExplorer/ApiExplorer和ASP.NET Web API: Generating a Web API help page using ApiExplorer)分别用于展示如何使用API打印Web API列表以及如何创建帮助文档。
所以我们创建帮助文档主要就是参照这篇文章就可以了ASP.NET Web API: Generating a Web API help page using ApiExplorer;作者在文章里面已经实现了一个IDocumentationProvider,它是通过代码的注释XML文档去生成,这是一个非常好的实现了:
public class XmlCommentDocumentationProvider : IDocumentationProvider
{
XPathNavigator _documentNavigator;
private const string _methodExpression = "/doc/members/member[@name='M:{0}']";
private static Regex nullableTypeNameRegex = new Regex(@"(.*\.Nullable)" + Regex.Escape("`1[[") + "([^,]*),.*");
public XmlCommentDocumentationProvider(string documentPath)
{
XPathDocument xpath = new XPathDocument(documentPath);
_documentNavigator = xpath.CreateNavigator();
}
public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)
{
ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;
if (reflectedParameterDescriptor != null)
{
XPathNavigator memberNode = GetMemberNode(reflectedParameterDescriptor.ActionDescriptor);
if (memberNode != null)
{
string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;
XPathNavigator parameterNode = memberNode.SelectSingleNode(string.Format("param[@name='{0}']", parameterName));
if (parameterNode != null)
{
return parameterNode.Value.Trim();
}
}
}
return "No Documentation Found.";
}
public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
{
XPathNavigator memberNode = GetMemberNode(actionDescriptor);
if (memberNode != null)
{
XPathNavigator summaryNode = memberNode.SelectSingleNode("summary");
if (summaryNode != null)
{
return summaryNode.Value.Trim();
}
}
return "No Documentation Found.";
}
private XPathNavigator GetMemberNode(HttpActionDescriptor actionDescriptor)
{
ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;
if (reflectedActionDescriptor != null)
{
string selectExpression = string.Format(_methodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));
XPathNavigator node = _documentNavigator.SelectSingleNode(selectExpression);
if (node != null)
{
return node;
}
}
return null;
}
private static string GetMemberName(MethodInfo method)
{
string name = string.Format("{0}.{1}", method.DeclaringType.FullName, method.Name);
var parameters = method.GetParameters();
if (parameters.Length != 0)
{
string[] parameterTypeNames = parameters.Select(param => ProcessTypeName(param.ParameterType.FullName)).ToArray();
name += string.Format("({0})", string.Join(",", parameterTypeNames));
}
return name;
}
private static string ProcessTypeName(string typeName)
{
//handle nullable
var result = nullableTypeNameRegex.Match(typeName);
if (result.Success)
{
return string.Format("{0}{{{1}}}", result.Groups[1].Value, result.Groups[2].Value);
}
return typeName;
}
}
把XML 文档的位置在Application_Start 中将IDocumentationProvider服务替换为我们的自定义服务。
var config = GlobalConfiguration.Configuration;
config.Services.Replace(typeof(IDocumentationProvider), new XmlCommentDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/MvcApplication2.XML")));
有个ApiExplorerSettingsAttribute 可以控制API是否在帮助页面上出现:
/// <summary>
/// DELETE api/values/5
/// </summary>
/// <param name="id"></param>
[ApiExplorerSettings(IgnoreApi = true)]
public void Delete(int id)
{
}
还可以控制整个ApiController 的文档是否发布出来,只需要通过在类级别应用ApiExplorerSettingsAttribute
[ApiExplorerSettings(IgnoreApi = true)]
public class MySpecialController : ApiController
{
通过IAPIExplorer 这个API我们可以为我们的Web API 做出很棒的文档了,而且这个接口的设计也是可扩展的。可以制作Web页面也可以制作一个HelpController来做,推荐封装成一个HelpController,这样就可以适应WebAPi的Web Host或者是Self Host了。
Mobile Development with C#, 该书详细介绍使用C#开发跨平台移动应用,基于Mono平台,使用.Net开发语言,开发多移动平台应用,iOS,Android,Windows Phone。
书籍下载
PDF格式:https://skydrive.live.com/?cid=33478a966734670f#cid=33478A966734670F&id=33478A966734670F%21446
EPUB格式:O'Reilly.Mobile.Development.with.CSharp.May.2012.epub