第一范文网 - 专业文章范例文档资料分享平台

OAuth2学习及DotNetOpenAuth部分源码研究

来源:用户分享 时间:2025/6/2 13:55:54 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

gePartEncoder, out encoder)) { encoder = encoders[messagePartEncoder] = (IMessagePartEncoder)Activator.CreateInstance(messagePartEncoder); } } return encoder; } }

ValueMapping类负责某对象与字符串之间的转换.converters字段缓存了各类型与ValueMapping之间的对应关系.在此对象首次加载时就会通过调用Map方法自动注册常见类型的转换方式.而构造函数则会从特性中或是从缓存中尝试获取ValueMapping. internalstruct ValueMapping { internalreadonly Func ValueToString; internalreadonly Func StringToValue; internal ValueMapping(Func toString, Func toOriginalString, Func toValue) : this() { this.ValueToString = toString; this.StringToValue = toValue; } internal ValueMapping(IMessagePartEncoder encoder) : this() { this.ValueToString = obj => (obj != null) ? encoder.Encode(obj) : nullString; this.StringToValue = str => (str != null) ? encoder.Decode(str) : null; } }

这里定义了两个委托,分别负责对象到字符串和字符串到对象的转换.如果传入一个IMessagePartEncoder类型,则将功能委托给此类型执行.

publicinterface IMessagePartEncoder { string Encode(object value); object Decode(string value); }

由于MessagePartAttribute特性拥有IMessagePartEncoder属性,这为自定义序列化转换提供了可能.比如上文曾说的各类令牌的基类AuthorizationDataBag

publicabstractclass AuthorizationDataBag : DataBag, IAuthorizationDescription { [MessagePart(Encoder = typeof(ScopeEncoder))] public HashSet Scope { get; privateset; } }

由于系统未定义从HashSet到字符串之间的转换,所以需要在标记特性时告知映射类ScopeEncoder

internalclass ScopeEncoder : IMessagePartEncoder { publicstring Encode(object value) { var scopes = (IEnumerable)value; return (scopes != null&& scopes.Any()) ? string.Join(\, scopes.ToArray()) : null; } publicobject Decode(string value) { return OAuthUtilities.SplitScopes(value); } } publicstaticclass OAuthUtilities { publicstatic HashSet SplitScopes(string scope) {varset = new HashSet(scope.Split(scopeDelimiter, StringSplitOptions.RemoveEmptyEntries), ScopeStringComparer);returnset; } }

可以看到,其实就是HashSet各项用逗号拼接.

上面获取的映射器最终会在取值或赋值时使用,下面这些赋值或取值的语法非常像.Net中反射的语法.

internalclass MessagePart { internalstring GetValue(IMessage message) { object value = this.GetValueAsObject(message); returnthis.ToString(value, false); } privatestring ToString(object value, bool originalString) { return originalString ? this.converter.ValueToOriginalString(value) : this.converter.

ValueToString(value); } internalvoid SetValue(IMessage message, string value) { this.SetValueAsObject(message, this.ToValue(value)); } privatevoid SetValueAsObject(IMessage message, object value) { if (this.property != null) { this.property.SetValue(message, value, null); } else { this.field.SetValue(message, value); } } privateobject ToValue(string value) { returnthis.converter.StringToValue(value); } }

MessageDescription对象用来描述对象

internalclass MessageDescription { private Dictionary mapping; internal MessageDescription(Type messageType, Version messageVersion) { this.MessageType = messageType; this.MessageVersion = messageVersion; this.ReflectMessageType(); } privatevoid ReflectMessageType() { this.mapping = new Dictionary(); Type currentType = this.MessageType; do { foreach (MemberInfo member in currentType.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) { if (member is PropertyInfo || member is FieldInfo) { MessagePartAttribute partAttribute = (from a in member.GetCustomAttributes(typeof(MessagePartAttribute), true).OfType() orderby a.MinVersionValue descending where a.MinVersionValue <= this.MessageVersion where a.MaxVersionValue >= this.MessageVersion select a).FirstOrDefault(); if (partAttribute != null) { MessagePart part = new MessagePart(member, partAttribute); if (this.

mapping.ContainsKey(part.Name)) { Logger.Messaging.WarnFormat( \ message part named {1}. Inherited members will be hidden.\, this.MessageType.Name, part.Name); } else { this.mapping.Add(part.Name, part); } } } } currentType = currentType.BaseType; } while (currentType != null); BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; this.Constructors = this.MessageType.GetConstructors(flags); } }

可以看到,此结象每一个实例都用来描述一个类,在初始化时会调用ReflectMessageType方法.此方法会反射并遍例所有类成员,并将标记了MessagePartAttribute特性的成员对成对应的MessagePart描述类并记录在对象内部的Dictionary类型字典中.

为了提高性能,作者引入了MessageDescriptionCollection类

internalclass MessageDescriptionCollection : IEnumerable { privatereadonly Dictionary reflectedMessageTypes = new Dictionary(); internal MessageDescription Get(Type messageType, Version messageVersion) { MessageTypeAndVersion key = new MessageTypeAndVersion(messageType, messageVersion); MessageDescription result; lock (this.reflectedMessageTypes) { this.reflectedMessageTypes.TryGetValue(key, out result); } if (result == null) { // Construct the message outside the lock.var newDescription = new MessageDescription(messageType, messageVersion); // Then use the lock again to either acquire what someone else has created in the meantime, or // set and use our own result.lock (this.reflectedMessageTypes) { if (!this.reflectedMessageTypes.TryGetValue(key, out result)) { this.reflectedMessageTypes[ke

搜索更多关于: OAuth2学习及DotNetOpenAuth部分源码研究 的文档
OAuth2学习及DotNetOpenAuth部分源码研究.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c784pk0utkd1od1e2lz3j_10.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top