Fun with dynamicobject dynamic and the settings table
What came before
In my previous post I discussed ways of making the settings table using Generics to have typed access to our properties. This required us to still pass in the name of our property as a string to a method.
User user = db.Users.First();if(user.Setting<bool>("IsAdministrator")){//yay, this user is an admin!}
Today we’re going to take advantage of dynamic to take it one step further.
The Goal
User user = db.Users.First();if(user.Settings.IsAdministrator){//yay, this user is an admin!}
We’re going to create a new class that inherits from DynamicObject. Doing so will allow us to utilize all the power of dynamics such as getting/setting members, calling methods, or type conversions. <a
The dynamic language runtime first checks to see if the property of our DynamicObject already exists and if it doesn’t find the property it calls TryGetMember or TrySetMember. This is what we’re going to use to return our settings property. Here is a barebones DynamicObject that uses aDictionary<string, object> to store values.
//These are essentially the same//user.Settings["IsAdministrator"]//user.Settings.IsAdministratorclassSettingsDynamicObject:DynamicObject{//used for cachingDictionary<string,object> _dictionary;publicSettingsDynamicObject(User user){
_dictionary =newDictionary<string,object>();}publicoverrideboolTrySetMember(SetMemberBinder binder,object value){
_dictionary[binder.Name]= value;returntrue;}publicoverrideboolTryGetMember(GetMemberBinder binder,outobject result){if( _dictionary.TryGetValue(binder.Name,out result)){returntrue;}}}
Adding our new database overrides
We’re now going to modify our overrides to pull values from the database if they don’t already exist in the _dictionary object and add our code to save the new values.
publicoverrideboolTrySetMember(SetMemberBinder binder,object value){SetDatabaseValue(binder.Name, value);
_dictionary[binder.Name]= value;returntrue;}publicoverrideboolTryGetMember(GetMemberBinder binder,outobject result){//check to see if the property already existsif( _dictionary.ContainsKey(binder.Name)&& _dictionary.TryGetValue(binder.Name,out result)){returntrue;}else{var setting =this.user
.UserSettings.SingleOrDefault(s => s.Name== binder.Name);if(setting ==null){
result =null;}else{
result =newBinaryFormatter().Deserialize(newSystem.IO.MemoryStream(setting.Value));
_dictionary[binder.Name]= result;}returntrue;}}privatevoidSetDatabaseValue(string name,object value){var setting =this.user.UserSettings.SingleOrDefault(s => s.Name== name);System.IO.MemoryStream ms =newSystem.IO.MemoryStream();newBinaryFormatter().Serialize(ms, value);if(setting ==null){
setting =newUserSetting(){Name= name,Type= value.GetType().ToString(),
setting.Value= ms.ToArray();this.user.UserSettings.Add(setting);}else{if(value !=null&& setting.Type!= value.GetType().FullName)thrownewInvalidCastException(string.Format("Unable to cast: {0} to {1}",
value.GetType().FullName, setting.Type));
setting.Value= ms.ToArray();}}
Modifying our existing user object
Now we have a new DynamicObject class that we can use to populate our settings but we’ll need to modify our existing User class to utilize the new Settings. One of the downsides is that we’ll have two exposed properties instead of one but I think it’s negligable.
publicclassUser{publicInt32UserID{get;set;}publicstringLoginID{get;set;}publicstringName{get;set;}publicstringPage{get;set;}publicstringPassword{get;set;}publicvirtualICollection<UserSetting>UserSettings{get;set;}publicvirtualdynamicSettings{get;set;}publicUser(){//We need to initialize the Settings to our new DynamicObjectSettings=newSettingsDynamicObject(this);}}
And there you have it. We now have a dynamic enabled settings property that makes our code slightly easier to read. I hope this helps you on your way to understanding c# 4.0’s new dynamic namespace.
– Ben
Update:
Fixed Constructor – thanks yesthatmcgurk
http://buildstarted.com/2010/08/23/fun-with-dynamicobject-dynamic-and-the-settings-table/
Fun with dynamicobject dynamic and the settings table的更多相关文章
- Creating a settings table that can handle almost any type of value
Update: Updated article here. Today I wanted to be able to have a table store any type of value as a ...
- 【原创】大叔问题定位分享(22)hive同时执行多个insert overwrite table只有1个可以执行
hive 2.1 一 问题 最近有一个场景,要向一个表的多个分区写数据,为了缩短执行时间,采用并发的方式,多个sql同时执行,分别写不同的分区,同时开启动态分区: set hive.exec.dyna ...
- CSharp 案例:用 Dynamic 来解决 DataTable 数值累加问题
需求说明 给定一个 DataTable,如果从中取出数值类型列的值并对其累加? 限制:不知该列是何种数值类型. 解决方案 1.将表转换为 IEnumerable<dynamic>,而后获取 ...
- [转]Dynamic SQL & Stored Procedure Usage in T-SQL
转自:http://www.sqlusa.com/bestpractices/training/scripts/dynamicsql/ Dynamic SQL & Stored Procedu ...
- DataTable转List<dynamic>
DataTable转List<dynamic> 最近做的一个项目,MVC+Ado.net.没有ORM很不习惯.找到一个办法,DataTable转List<dynamic>,这样 ...
- Dynamic view
Views are a useful feature of SQL databases, letting us create virtual tables based on SQL select st ...
- Working with the Dynamic Type in C#
Working with the Dynamic Type in C# https://www.red-gate.com/simple-talk/dotnet/c-programming/workin ...
- Dynamic Type
啥是 Dynamic Type 动态字体,即视力不好的用户,调整了默认字体的大小,开发者应该根据这个设置,动态改变界面的字体等,保证用户能看得清楚. 这个还是蛮重要的,视力不好的人越来越多. 用户在哪 ...
- Deploying JRE (Native Plug-in) for Windows Clients in Oracle E-Business Suite Release 12 (文档 ID 393931.1)
In This Document Section 1: Overview Section 2: Pre-Upgrade Steps Section 3: Upgrade and Configurati ...
随机推荐
- Python函数小结(1)--参数类型(*, ** 的区别), 闭包
刚开始学习python,python相对于java确实要简洁易用得多.内存回收类似hotspot的可达性分析, 不可变对象也如同java得Integer类型,with函数类似新版本C++的特性,总体来 ...
- [vim]插件ctrlp
ctrlp 这个插件可以快速搜索你的文件或者缓冲区 这样很多时候都不必打开nerdtree了. 直接利用快捷键C-p打开搜索命令.
- MySQL 学习笔记 (limit offset)
select * from table limit (10000,10);这样是很慢的,因为要定位 比较快的写法是 select * from table where id >=(select ...
- python的工作记录B
这次很强了.就差最后一步,判断一下SVN的版本是否是真的库里的. #!/usr/bin/env python # -*- coding: utf-8 -*- import os,sys,command ...
- JAVA语言学校的危险性
Java语言学校的危险性(译文) 作者: 阮一峰 日期: 2008年12月 7日 下面的文章是More Joel on Software一书的第8篇. 我觉得翻译难度很大,整整两个工作日,每天8小时以 ...
- 一位搬家师傅的O2O之旅
一位搬家师傅的O2O之旅 By 诸神之黄昏 | 2014/08/14 [核心提示] 一位普通的搬家师傅,无意中被卷入如火如荼的 O2O 浪潮,起初,互联网让他尝到了甜头,后来则是更多的困惑和不解. 再 ...
- linux下,FTP服务相关
虚拟机上安装完CentOS 6.5后,使用FTP工具(FlashFXP)来上传文件到虚拟机的linux,结果发现连接不上.现在解决了,解决方法总结一下: 1.先检查有没有安装ftp.好像包括两个部分, ...
- usaco5.5-Hidden Passwords
最小表示法,感觉可以做成个模板,第一次RE是因为字符串长度变2倍了而我把数组开小了 Executing... Test 1: TEST OK [0.008 secs, 3760 KB] Tes ...
- CCF软考---《有趣的数》
脑子一热报了CCF的软测..但是又觉得好像并没有什么卵用,就当为蓝桥杯预热然后顺便去软件学院玩一玩吧,遇到一个有意思的题: time limits : 1s 问题描述 我们把一个数称为有趣的,当且仅当 ...
- [教程]隐藏ActionBar中的MenuItem
有时候我们需要在不同的时候改变ActionBar中MenuItem的项数,或者隐藏某些MenuItem,百度上找了很久没什好资料,还是Google了一下,StackOverFlow上有大神解决了. 先 ...