PageRenderTime 60ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/SolutionFramework/Microsoft.VisualStudio.ServiceModel.DomainServices.Tools.10.0/Microsoft/VisualStudio/ServiceModel/DomainServices/Tools/BusinessLogicContext.cs

#
C# | 400 lines | 371 code | 29 blank | 0 comment | 40 complexity | 3386c59f26de19f19526adad70778b7c MD5 | raw file
Possible License(s): Apache-2.0, LGPL-3.0
  1. namespace Microsoft.VisualStudio.ServiceModel.DomainServices.Tools
  2. {
  3. using System;
  4. using System.CodeDom;
  5. using System.Collections.Generic;
  6. using System.Globalization;
  7. using System.Reflection;
  8. using System.ServiceModel.DomainServices.Hosting;
  9. using System.Linq;
  10. internal class BusinessLogicContext
  11. {
  12. private Microsoft.VisualStudio.ServiceModel.DomainServices.Tools.ContextData _contextData;
  13. private Type _contextType;
  14. private List<BusinessLogicEntity> _entities;
  15. private string _name;
  16. private static int uniqueContextID;
  17. private const string UserDataHelperMethods = "HelperMethods";
  18. public BusinessLogicContext(Type contextType, string name)
  19. {
  20. this._contextType = contextType;
  21. this._name = name;
  22. }
  23. protected virtual bool CanGeneratePropertyOfType(Type type)
  24. {
  25. type = TypeUtilities.GetElementType(type);
  26. if (TypeUtilities.IsPredefinedType(type))
  27. {
  28. return true;
  29. }
  30. foreach (BusinessLogicEntity entity in this.Entities)
  31. {
  32. if (entity.ClrType == type)
  33. {
  34. return true;
  35. }
  36. }
  37. return false;
  38. }
  39. protected virtual CodeTypeDeclaration CreateBusinessLogicClass(CodeGenContext codeGenContext, CodeNamespace codeNamespace, string className)
  40. {
  41. CodeTypeDeclaration declaration = CodeGenUtilities.CreateTypeDeclaration(className, codeNamespace.Name);
  42. declaration.BaseTypes.Add(BusinessLogicClassConstants.DomainServiceTypeName);
  43. return declaration;
  44. }
  45. protected virtual IEnumerable<BusinessLogicEntity> CreateEntities()
  46. {
  47. return new BusinessLogicEntity[0];
  48. }
  49. protected virtual bool GenerateAdditionalMetadataClasses(CodeGenContext codeGenContext, string optionalSuffix, BusinessLogicEntity entity)
  50. {
  51. return false;
  52. }
  53. protected void GenerateBusinessLogicClass(CodeGenContext codeGenContext, string className, string namespaceName)
  54. {
  55. string str;
  56. if (codeGenContext == null)
  57. {
  58. throw new ArgumentNullException("codeGenContext");
  59. }
  60. if (string.IsNullOrEmpty(className))
  61. {
  62. throw new ArgumentNullException("className");
  63. }
  64. if (string.IsNullOrEmpty(namespaceName))
  65. {
  66. throw new ArgumentNullException("namespaceName");
  67. }
  68. CodeNamespace orGenNamespace = codeGenContext.GetOrGenNamespace(namespaceName);
  69. CodeTypeDeclaration declaration = this.CreateBusinessLogicClass(codeGenContext, orGenNamespace, className);
  70. orGenNamespace.Types.Add(declaration);
  71. if (this.ContextType == null)
  72. {
  73. str = Resources.BusinessLogicClass_Class_Remarks_Empty;
  74. }
  75. else
  76. {
  77. str = string.Format(CultureInfo.CurrentCulture, Resources.BusinessLogicClass_Class_Remarks, new object[] { this.ContextType.Name });
  78. }
  79. declaration.Comments.Add(new CodeCommentStatement(str, false));
  80. if (this.ContextType != null)
  81. {
  82. str = codeGenContext.IsCSharp ? Resources.BusinessLogicClass_RequiresAuthentication_CSharp : Resources.BusinessLogicClass_RequiresAuthentication_VB;
  83. declaration.Comments.Add(new CodeCommentStatement(str, false));
  84. }
  85. if (this.IsClientAccessEnabled)
  86. {
  87. CodeAttributeDeclaration declaration2 = CodeGenUtilities.CreateAttributeDeclaration(BusinessLogicClassConstants.EnableClientAccessAttributeTypeName);
  88. declaration.CustomAttributes.Add(declaration2);
  89. }
  90. else
  91. {
  92. declaration.Comments.Add(new CodeCommentStatement(Resources.BusinessLogicClass_EnableClientAccess_Comment));
  93. }
  94. foreach (BusinessLogicEntity entity in from e in this.Entities
  95. orderby e.Name
  96. select e)
  97. {
  98. if (entity.IsIncluded)
  99. {
  100. CodeGenUtilities.AddImportIfNeeded(orGenNamespace, entity.ClrType.Namespace);
  101. this.GenerateEntityDomainOperationEntries(codeGenContext, declaration, entity);
  102. }
  103. }
  104. Dictionary<string, CodeTypeMember> helperMemberDictionary = GetHelperMemberDictionary(declaration);
  105. foreach (string str2 in from s in helperMemberDictionary.Keys
  106. orderby s
  107. select s)
  108. {
  109. declaration.Members.Add(helperMemberDictionary[str2]);
  110. }
  111. if (this.IsODataEndpointEnabled)
  112. {
  113. codeGenContext.AddReference(typeof(ODataEndpointFactory).Assembly.FullName);
  114. }
  115. }
  116. public GeneratedCode GenerateBusinessLogicClass(string language, string className, string namespaceName, string rootNamespace)
  117. {
  118. using (CodeGenContext context = new CodeGenContext(language, rootNamespace))
  119. {
  120. this.GenerateBusinessLogicClass(context, className, namespaceName);
  121. return context.GenerateCode();
  122. }
  123. }
  124. protected virtual void GenerateDeleteMethod(CodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass, BusinessLogicEntity entity)
  125. {
  126. }
  127. internal void GenerateEntityDomainOperationEntries(CodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass, BusinessLogicEntity entity)
  128. {
  129. CodeMemberMethod method = this.GenerateSelectMethod(codeGenContext, businessLogicClass, entity);
  130. if ((method != null) && this.IsODataEndpointEnabled)
  131. {
  132. CodeAttributeDeclaration declaration = new CodeAttributeDeclaration(new CodeTypeReference("Query"), new CodeAttributeArgument[] { new CodeAttributeArgument("IsDefault", new CodePrimitiveExpression(true)) });
  133. method.CustomAttributes.Add(declaration);
  134. }
  135. if (entity.IsEditable)
  136. {
  137. this.GenerateInsertMethod(codeGenContext, businessLogicClass, entity);
  138. this.GenerateUpdateMethod(codeGenContext, businessLogicClass, entity);
  139. this.GenerateDeleteMethod(codeGenContext, businessLogicClass, entity);
  140. }
  141. }
  142. internal static void GenerateHelperMemberIfNecessary(CodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass, string helperMemberName, Func<CodeTypeMember> generatorCallback)
  143. {
  144. Dictionary<string, CodeTypeMember> helperMemberDictionary = GetHelperMemberDictionary(businessLogicClass);
  145. if (!helperMemberDictionary.ContainsKey(helperMemberName))
  146. {
  147. CodeTypeMember member = generatorCallback();
  148. if (member != null)
  149. {
  150. helperMemberDictionary[helperMemberName] = member;
  151. }
  152. }
  153. }
  154. protected virtual void GenerateInsertMethod(CodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass, BusinessLogicEntity entity)
  155. {
  156. }
  157. internal bool GenerateMetadataClass(CodeGenContext codeGenContext, string optionalSuffix, Type type)
  158. {
  159. if (TypeUtilities.GetAssociatedMetadataType(type) != null)
  160. {
  161. return false;
  162. }
  163. string name = type.Name;
  164. string namespaceName = type.Namespace;
  165. bool flag = !string.IsNullOrEmpty(optionalSuffix);
  166. if (flag)
  167. {
  168. name = name + optionalSuffix;
  169. namespaceName = namespaceName + optionalSuffix;
  170. }
  171. CodeNamespace orGenNamespace = codeGenContext.GetOrGenNamespace(namespaceName);
  172. if (flag)
  173. {
  174. CodeGenUtilities.AddImportIfNeeded(orGenNamespace, type.Namespace);
  175. }
  176. string typeName = name + "Metadata";
  177. string str4 = name + "." + typeName;
  178. CodeTypeDeclaration declaration = null;
  179. declaration = CodeGenUtilities.CreateTypeDeclaration(name, namespaceName);
  180. declaration.IsPartial = true;
  181. declaration.TypeAttributes = TypeAttributes.Public;
  182. declaration.Comments.Add(new CodeCommentStatement(string.Format(CultureInfo.CurrentCulture, Resources.BusinessLogicClass_Entity_Partial_Class_Remarks, new object[] { typeName, name }), false));
  183. CodeAttributeDeclaration declaration2 = CodeGenUtilities.CreateAttributeDeclaration(BusinessLogicClassConstants.MetadataTypeAttributeTypeName);
  184. CodeAttributeArgument argument = new CodeAttributeArgument(new CodeTypeOfExpression(str4));
  185. declaration2.Arguments.Add(argument);
  186. declaration.CustomAttributes.Add(declaration2);
  187. CodeTypeDeclaration buddyClass = CodeGenUtilities.CreateTypeDeclaration(typeName, namespaceName);
  188. buddyClass.TypeAttributes = TypeAttributes.Sealed | TypeAttributes.NestedAssembly;
  189. bool flag2 = false;
  190. buddyClass.Comments.Add(new CodeCommentStatement(string.Format(CultureInfo.CurrentCulture, Resources.Buddy_Class_Remarks, new object[] { type.Name })));
  191. string text = codeGenContext.IsCSharp ? Resources.Buddy_Class_Remarks_CSharp : Resources.Buddy_Class_Remarks_VB;
  192. buddyClass.Comments.Add(new CodeCommentStatement(text, false));
  193. CodeConstructor constructor = new CodeConstructor {
  194. Attributes = MemberAttributes.Private
  195. };
  196. constructor.Comments.Add(new CodeCommentStatement(Resources.BusinessLogicClass_Private_Ctor_Comment));
  197. buddyClass.Members.Add(constructor);
  198. foreach (PropertyInfo info in from p in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
  199. orderby p.Name
  200. select p)
  201. {
  202. Type propertyType = info.PropertyType;
  203. if ((propertyType.IsVisible && (info.GetGetMethod() != null)) && this.CanGeneratePropertyOfType(propertyType))
  204. {
  205. CodeGenUtilities.AddImportIfNeeded(orGenNamespace, info.PropertyType.Namespace);
  206. CodeSnippetTypeMember member = CodeGenUtilities.CreateAutomaticPropertyDeclaration(codeGenContext, buddyClass, info, !string.IsNullOrEmpty(orGenNamespace.Name));
  207. buddyClass.Members.Add(member);
  208. flag2 = true;
  209. }
  210. }
  211. if (flag2)
  212. {
  213. orGenNamespace.Types.Add(declaration);
  214. declaration.Members.Add(buddyClass);
  215. }
  216. return flag2;
  217. }
  218. protected bool GenerateMetadataClasses(CodeGenContext codeGenContext, string optionalSuffix)
  219. {
  220. bool flag = false;
  221. if (this.NeedToGenerateMetadataClasses)
  222. {
  223. foreach (BusinessLogicEntity entity in from e in this.Entities
  224. orderby e.Name
  225. select e)
  226. {
  227. if (entity.IsIncluded)
  228. {
  229. flag |= this.GenerateMetadataClass(codeGenContext, optionalSuffix, entity.ClrType);
  230. flag |= this.GenerateAdditionalMetadataClasses(codeGenContext, optionalSuffix, entity);
  231. }
  232. }
  233. }
  234. return flag;
  235. }
  236. public GeneratedCode GenerateMetadataClasses(string language, string rootNamespace, string optionalSuffix)
  237. {
  238. using (CodeGenContext context = new CodeGenContext(language, rootNamespace))
  239. {
  240. if (this.GenerateMetadataClasses(context, optionalSuffix))
  241. {
  242. return context.GenerateCode();
  243. }
  244. }
  245. return new GeneratedCode();
  246. }
  247. protected virtual CodeMemberMethod GenerateSelectMethod(CodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass, BusinessLogicEntity entity)
  248. {
  249. return null;
  250. }
  251. protected virtual void GenerateUpdateMethod(CodeGenContext codeGenContext, CodeTypeDeclaration businessLogicClass, BusinessLogicEntity entity)
  252. {
  253. }
  254. protected static Dictionary<string, CodeTypeMember> GetHelperMemberDictionary(CodeTypeDeclaration businessLogicClass)
  255. {
  256. Dictionary<string, CodeTypeMember> dictionary = null;
  257. if (businessLogicClass.UserData.Contains("HelperMethods"))
  258. {
  259. return (businessLogicClass.UserData["HelperMethods"] as Dictionary<string, CodeTypeMember>);
  260. }
  261. dictionary = new Dictionary<string, CodeTypeMember>();
  262. businessLogicClass.UserData["HelperMethods"] = dictionary;
  263. return dictionary;
  264. }
  265. public Microsoft.VisualStudio.ServiceModel.DomainServices.Tools.ContextData ContextData
  266. {
  267. get
  268. {
  269. if (this._contextData == null)
  270. {
  271. Microsoft.VisualStudio.ServiceModel.DomainServices.Tools.ContextData data = new Microsoft.VisualStudio.ServiceModel.DomainServices.Tools.ContextData {
  272. Name = this.NameAndDataAccessLayerName,
  273. IsClientAccessEnabled = true,
  274. ID = uniqueContextID++
  275. };
  276. this._contextData = data;
  277. }
  278. return this._contextData;
  279. }
  280. set
  281. {
  282. this._contextData = value;
  283. }
  284. }
  285. public Type ContextType
  286. {
  287. get
  288. {
  289. return this._contextType;
  290. }
  291. }
  292. public virtual string DataAccessLayerName
  293. {
  294. get
  295. {
  296. return null;
  297. }
  298. }
  299. public IEnumerable<BusinessLogicEntity> Entities
  300. {
  301. get
  302. {
  303. if (this._entities == null)
  304. {
  305. try
  306. {
  307. this._entities = new List<BusinessLogicEntity>(this.CreateEntities());
  308. }
  309. catch (Exception exception)
  310. {
  311. if (exception is OutOfMemoryException)
  312. {
  313. throw;
  314. }
  315. this._entities = new List<BusinessLogicEntity>();
  316. }
  317. this._entities.Sort((Comparison<BusinessLogicEntity>) ((x, y) => string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase)));
  318. }
  319. return this._entities;
  320. }
  321. }
  322. public IEnumerable<EntityData> EntityDataItems
  323. {
  324. get
  325. {
  326. return (from ble in this.Entities select ble.EntityData);
  327. }
  328. }
  329. public bool IsClientAccessEnabled
  330. {
  331. get
  332. {
  333. return this.ContextData.IsClientAccessEnabled;
  334. }
  335. }
  336. public bool IsODataEndpointEnabled
  337. {
  338. get
  339. {
  340. return this.ContextData.IsODataEndpointEnabled;
  341. }
  342. }
  343. public string Name
  344. {
  345. get
  346. {
  347. return this.ContextData.Name;
  348. }
  349. }
  350. public string NameAndDataAccessLayerName
  351. {
  352. get
  353. {
  354. string str = this._name;
  355. string dataAccessLayerName = this.DataAccessLayerName;
  356. if (!string.IsNullOrEmpty(dataAccessLayerName))
  357. {
  358. return string.Format(CultureInfo.CurrentCulture, Resources.BusinessLogicClass_Name_And_Technology, new object[] { str, dataAccessLayerName });
  359. }
  360. return str;
  361. }
  362. }
  363. internal virtual bool NeedToGenerateMetadataClasses
  364. {
  365. get
  366. {
  367. return true;
  368. }
  369. }
  370. }
  371. }