private void CheckSharePointRuntimeVersion() { // Require minimum SP2013 SP1 which is 15.0.4569.1000 // We need 15.0.4569.1000 as this allows to create content types with particular ID // If current assembly version is lover than 15.0.4569.1000, then we gonna have missing field exception on ContentTypeCreationInformation.Id // http://blogs.technet.com/b/steve_chen/archive/2013/03/26/3561010.aspx var minimalVersion = new Version("15.0.4569.1000"); var spAssembly = typeof(Field).Assembly; var spAssemblyFileVersion = FileVersionInfo.GetVersionInfo(spAssembly.Location); var versionInfo = new Version(spAssemblyFileVersion.ProductVersion); TraceService.InformationFormat((int)LogEventId.ModelProcessing, "CSOM - CheckSharePointRuntimeVersion. Required minimal version :[{0}]. Current version: [{1}] Location: [{2}]", new object[] { minimalVersion, spAssemblyFileVersion, spAssemblyFileVersion.ProductVersion }); if (versionInfo < minimalVersion) { TraceService.Error((int)LogEventId.ModelProcessing, "CSOM - CheckSharePointRuntimeVersion failed. Throwing SPMeta2NotSupportedException"); var exceptionMessage = string.Empty; exceptionMessage += string.Format("SPMeta2.CSOM.dll requires at least SP2013 SP1 runtime ({0}).{1}", minimalVersion, Environment.NewLine); exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll version:[{0}].{1}", spAssemblyFileVersion.ProductVersion, Environment.NewLine); exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll location:[{0}].{1}", spAssembly.Location, Environment.NewLine); throw new SPMeta2NotSupportedException(exceptionMessage); } }
// AutoDetectSharePointPersistenceStorage protected virtual List <PersistenceStorageServiceBase> ResolvePersistenceStorages(object modelHost, ModelNode modelNode) { if (Configuration == null) { return(new List <PersistenceStorageServiceBase>()); } if (Configuration.AutoDetectSharePointPersistenceStorage) { var rootModelNodeType = modelNode.Value.GetType(); TraceService.InformationFormat(0, "Detecting SharePoint persistence storage implementation for root definitin type:[{0}]", rootModelNodeType); var currentStorageServices = ServiceContainer.Instance.GetServices <SharePointPersistenceStorageServiceBase>(); SharePointPersistenceStorageServiceBase targetService = null; var typedModelHost = modelHost.WithAssertAndCast <ModelHostBase>("modelHost", v => v.RequireNotNull()); foreach (var service in currentStorageServices) { if (service.TargetDefinitionTypes.Contains(rootModelNodeType)) { var serviceTypeName = service.GetType().Name; // cause it could be multiple service registrations here by both CSOM and SSOM // we need to know the context coming from the top and then resolve correct service for the API if (typedModelHost.IsSSOM && serviceTypeName.Contains("SSOM")) { targetService = service; break; } if (typedModelHost.IsCSOM && serviceTypeName.Contains("CSOM")) { targetService = service; break; } } } if (targetService == null) { throw new SPMeta2Exception( string.Format("Coudn't find SharePoint persistence storage implementation for root definitin type:[{0}]", rootModelNodeType)); } TraceService.InformationFormat(0, "Initialilize persistence storage [{0}] with model host", targetService.GetType()); targetService.InitialiseFromModelHost(modelHost); TraceService.Information(0, "Returning persistence storage implementation"); var result = new List <PersistenceStorageServiceBase>(); result.Add(targetService); return(result); } return(Configuration.PersistenceStorages); }
public void RegisterModelHandler(ModelHandlerBase modelHandlerType) { TraceService.InformationFormat((int)LogEventId.CoreCalls, "RegisterModelHandler of type:[{0}] for target type:[{1}]", new object[] { modelHandlerType.GetType(), modelHandlerType.TargetType }); if (!ModelHandlers.ContainsKey(modelHandlerType.TargetType)) { TraceService.VerboseFormat((int)LogEventId.CoreCalls, "Model handler for type [{0}] has not been registered yet. Registering.", new object[] { modelHandlerType.GetType() }); ModelHandlers.Add(modelHandlerType.TargetType, modelHandlerType); } else { TraceService.VerboseFormat((int)LogEventId.CoreCalls, "Model handler for type [{0}] has been registered. Skipping.", new object[] { modelHandlerType.GetType() }); } }
protected virtual void CheckCSOMRuntimeVersion() { // Require minimum SP2013 SP1 which is 15.0.4569.1000 // We need 15.0.4569.1000 as this allows to create content types with particular ID // If current assembly version is lover than 15.0.4569.1000, then we gonna have missing field exception on ContentTypeCreationInformation.Id // http://blogs.technet.com/b/steve_chen/archive/2013/03/26/3561010.aspx var spAssembly = GetCSOMRuntimeAssembly(); var versionInfo = GetCSOMRuntimeVersion(); var assemblyLocation = string.Empty; // RequireCSOMRuntimeVersionDeploymentService does not work under Azure Funtions #962 // https://github.com/SubPointSolutions/spmeta2/issues/962 try { assemblyLocation = spAssembly.Location; } catch (Exception assemblyLocationLoadException) { assemblyLocation = string.Format("Coudn't load .Location property. Exception was:[{0}]", assemblyLocationLoadException); } TraceService.InformationFormat((int)LogEventId.ModelProcessing, "CSOM - CheckSharePointRuntimeVersion. Required minimal version :[{0}]. Current version: [{1}] Location: [{2}]", new object[] { MinimalVersion, versionInfo, assemblyLocation }); if (versionInfo.Major == 14) { // TODO, SP2010 check later } else if (versionInfo.Major == 15) { if (versionInfo < SP2013MinimalVersion) { TraceService.Error((int)LogEventId.ModelProcessing, "CSOM - CheckSharePointRuntimeVersion failed. Throwing SPMeta2NotSupportedException"); var exceptionMessage = string.Empty; exceptionMessage += string.Format("SPMeta2.CSOM.dll requires at least SP2013 SP1 runtime ({0}).{1}", MinimalVersion, Environment.NewLine); exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll version:[{0}].{1}", versionInfo.Major, Environment.NewLine); exceptionMessage += string.Format(" Current Microsoft.SharePoint.Client.dll location:[{0}].{1}", assemblyLocation, Environment.NewLine); throw new SPMeta2NotSupportedException(exceptionMessage); } } else if (versionInfo.Major == 16) { // TODO, SP2016 check later } }
protected Web GetExistingWeb(Site site, Web parentWeb, string currentWebUrl) { TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Entering GetExistingWeb()"); var result = false; var srcUrl = currentWebUrl.ToLower().Trim('/').Trim('\\'); // for self-hosting and '/' if (parentWeb.Url.ToLower().Trim('/').Trim('\\').EndsWith(srcUrl)) { return(parentWeb); } var context = parentWeb.Context; Web web = null; var scope = new ExceptionHandlingScope(context); using (scope.StartScope()) { using (scope.StartTry()) { web = site.OpenWeb(currentWebUrl); } using (scope.StartCatch()) { } } TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()"); context.ExecuteQueryWithTrace(); if (!scope.HasException && web != null && web.ServerObjectIsNull == false) { TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Found web with URL: [{0}]", currentWebUrl); context.Load(web); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()"); context.ExecuteQueryWithTrace(); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Exciting GetExistingWeb()"); return(web); } TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Can't find web with URL: [{0}]. Returning NULL.", currentWebUrl); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Exciting GetExistingWeb()"); return(null); }
protected ContentType FindListContentType(List list, ContentTypeLinkDefinition contentTypeLinkModel) { ContentType result = null; // TODO // https://github.com/SubPointSolutions/spmeta2/issues/68 // if content type name was not provided, this fails // should be re-done by ID and Name // OOTB content types could be binded by ID, and custom content types might be binded by name // trying to find by name if (!string.IsNullOrEmpty(contentTypeLinkModel.ContentTypeName)) { TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "ContentTypeName is not NULL. Trying to find list content type by ContentTypeName: [{0}]", contentTypeLinkModel.ContentTypeName); result = list.ContentTypes.FindByName(contentTypeLinkModel.ContentTypeName); } // trying to find by content type id // will never be resolved, actually // list content types have different ID //if (result == null && !string.IsNullOrEmpty(contentTypeLinkModel.ContentTypeId)) // result = list.ContentTypes.GetById(contentTypeLinkModel.ContentTypeId); // trying to find by beat match if (result == null) { TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Trying to find list content type by ContentTypeId: [{0}]", contentTypeLinkModel.ContentTypeId); // No SPContentTypeCollection.BestMatch() method avialable. // http://officespdev.uservoice.com/forums/224641-general/suggestions/6356289-expose-spcontenttypecollection-bestmatch-for-csom // TODO, correct best match impl foreach (var contentType in list.ContentTypes) { if (contentType.Id.ToString().ToUpper().StartsWith(contentTypeLinkModel.ContentTypeId.ToUpper())) { result = contentType; } } } return(result); }
/// <summary> /// Promotes a model event outside of the model handler. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> protected void InvokeOnModelEvent(object sender, ModelEventArgs args) { TraceService.InformationFormat((int)LogEventId.CoreCalls, "Entering InvokeOnModelEvent with sender: [{0}] and args: [{1}]", new object[] { sender, args }); if (OnModelEvent != null) { TraceService.VerboseFormat((int)LogEventId.CoreCalls, "OnModelEvent is not NULL. Calling OnModelEvent with sender: [{0}] and args: [{1}]", new object[] { sender, args }); OnModelEvent.Invoke(this, args); } else { TraceService.Verbose((int)LogEventId.CoreCalls, "OnModelEvent is NULL. Skipping."); } TraceService.InformationFormat((int)LogEventId.CoreCalls, "Leaving InvokeOnModelEvent with sender: [{0}] and args: [{1}]", new object[] { sender, args }); }
public override void Traverse(object modelHost, ModelNode modelNode) { try { var modelDefinition = modelNode.Value as DefinitionBase; var modelHandler = OnModelHandlerResolve(modelNode); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelFullyProcessing for model: [{0}].", modelNode); if (OnModelFullyProcessing != null) { OnModelFullyProcessing(modelNode); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelProcessing for model: [{0}].", modelNode); if (OnModelProcessing != null) { OnModelProcessing(modelNode); } var requireselfProcessing = modelDefinition.RequireSelfProcessing || modelNode.Options.RequireSelfProcessing; TraceService.InformationFormat((int)LogEventId.ModelProcessing, "Deploying model [{0}] RSP: [{1}] : [{2}].", new[] { modelNode.Value.GetType().Name, requireselfProcessing.ToString(), modelNode.Value.ToString() }); if (requireselfProcessing) { modelHandler.DeployModel(modelHost, modelNode.Value); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelProcessed for model: [{0}].", modelNode); if (OnModelProcessed != null) { OnModelProcessed(modelNode); } var childModelTypes = GetSortedChildModelTypes(modelNode); foreach (var childModelType in childModelTypes) { TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Starting processing child models of type: [{0}].", new object[] { childModelType.Key }); var childModels = modelNode.GetChildModels(childModelType.Key).ToList(); ModelWeighService.SortChildModelNodes(modelNode, childModels); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Found [{0}] models of type: [{1}].", new object[] { childModels.Count(), childModelType.Key }); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnChildModelsProcessing of type: [{0}].", new object[] { childModelType.Key }); if (OnChildModelsProcessing != null) { OnChildModelsProcessing(modelNode, childModelType.Key, childModels); } foreach (var childModel in childModels) { TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Starting resolving model host of type: [{0}].", new object[] { childModelType.Key }); modelHandler.WithResolvingModelHost(new ModelHostResolveContext { ModelHost = modelHost, Model = modelDefinition, ChildModelType = childModelType.Key, ModelNode = modelNode, Action = childModelHost => { Traverse(childModelHost, childModel); } }); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Finishing resolving model host of type: [{0}].", new object[] { childModelType.Key }); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnChildModelsProcessed of type: [{0}].", new object[] { childModelType.Key }); if (OnChildModelsProcessed != null) { OnChildModelsProcessed(modelNode, childModelType.Key, childModels); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Finishing processing child models of type: [{0}].", new object[] { childModelType.Key }); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelFullyProcessed for model: [{0}].", modelNode); if (OnModelFullyProcessed != null) { OnModelFullyProcessed(modelNode); } } catch (Exception e) { if (e is SPMeta2ModelDeploymentException) { throw; } throw new SPMeta2ModelDeploymentException("There was an error while provisioning definition. Check ModelNode prop.", e) { ModelNode = modelNode, }; } }
public override void Traverse(object modelHost, ModelNode modelNode) { try { if (CurrentModelPath.Count == 0) { OnBeforeDeployModel(modelHost, modelNode); } CurrentModelPath.Push(modelNode); var modelDefinition = modelNode.Value as DefinitionBase; var modelHandler = OnModelHandlerResolve(modelNode); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelFullyProcessing for model: [{0}].", modelNode); if (OnModelFullyProcessing != null) { OnModelFullyProcessing(modelNode); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelProcessing for model: [{0}].", modelNode); OnBeforeDeployModelNode(modelHost, modelNode); if (OnModelProcessing != null) { OnModelProcessing(modelNode); } //var requireselfProcessing = modelDefinition.RequireSelfProcessing || modelNode.Options.RequireSelfProcessing; var requireselfProcessing = modelNode.Options.RequireSelfProcessing; TraceService.InformationFormat((int)LogEventId.ModelProcessing, "Deploying model [{0}] RSP: [{1}] : [{2}].", new[] { modelNode.Value.GetType().Name, requireselfProcessing.ToString(), modelNode.Value.ToString() }); if (requireselfProcessing) { try { modelHandler.DeployModel(modelHost, modelNode.Value); } catch (Exception e) { var onExceptionArgs = new ModelTreeTraverseServiceExceptionEventArgs { Handled = false, Exception = e }; if (OnException != null) { OnException(this, onExceptionArgs); } if (!onExceptionArgs.Handled) { throw; } } } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelProcessed for model: [{0}].", modelNode); // call up before OnModelProcessed // Incremental provision real time trace problems #978 // https://github.com/SubPointSolutions/spmeta2/issues/978 OnAfterDeployModelNode(modelHost, modelNode); if (OnModelProcessed != null) { OnModelProcessed(modelNode); } var childModelTypes = GetSortedChildModelTypes(modelNode); foreach (var childModelType in childModelTypes) { TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Starting processing child models of type: [{0}].", new object[] { childModelType.Key }); var childModels = modelNode.GetChildModels(childModelType.Key).ToList(); ModelWeighService.SortChildModelNodes(modelNode, childModels); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Found [{0}] models of type: [{1}].", new object[] { childModels.Count(), childModelType.Key }); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnChildModelsProcessing of type: [{0}].", new object[] { childModelType.Key }); if (OnChildModelsProcessing != null) { OnChildModelsProcessing(modelNode, childModelType.Key, childModels); } foreach (var childModel in childModels) { TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Starting resolving model host of type: [{0}].", new object[] { childModelType.Key }); modelHandler.WithResolvingModelHost(new ModelHostResolveContext { ModelHost = modelHost, Model = modelDefinition, ChildModelType = childModelType.Key, ModelNode = modelNode, Action = childModelHost => { Traverse(childModelHost, childModel); } }); TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Finishing resolving model host of type: [{0}].", new object[] { childModelType.Key }); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnChildModelsProcessed of type: [{0}].", new object[] { childModelType.Key }); if (OnChildModelsProcessed != null) { OnChildModelsProcessed(modelNode, childModelType.Key, childModels); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Finishing processing child models of type: [{0}].", new object[] { childModelType.Key }); } TraceService.VerboseFormat((int)LogEventId.ModelProcessing, "Raising OnModelFullyProcessed for model: [{0}].", modelNode); if (OnModelFullyProcessed != null) { OnModelFullyProcessed(modelNode); } } catch (Exception e) { var onExceptionArgs = new ModelTreeTraverseServiceExceptionEventArgs { Handled = false, Exception = e }; if (OnException != null) { OnException(this, onExceptionArgs); } if (!onExceptionArgs.Handled) { if (e is SPMeta2ModelDeploymentException) { throw; } throw new SPMeta2ModelDeploymentException( "There was an error while provisioning definition. Check ModelNode prop.", e) { ModelNode = modelNode, }; } } finally { if (CurrentModelPath.Count != 0) { CurrentModelPath.Pop(); } if (CurrentModelPath.Count == 0) { OnAfterDeployModel(modelHost, modelNode); } } }
protected override void OnBeforeDeployModel(object modelHost, ModelNode modelNode) { base.OnBeforeDeployModel(modelHost, modelNode); // clean up current model hash CurrentModelHash = new ModelHash(); ClearCaches(); TraceService.InformationFormat(0, "Starting incremental provision with EnableCaching = {0}", EnableCaching); var storages = ResolvePersistenceStorages(modelHost, modelNode); // restore previous one if (Configuration != null && storages.Count() > 0) { TraceService.Information(0, "Model hash restore: found [{0}] storage impl in Configuration.PersistenceStorages. Automatic model hash management is used"); var modelIdProperty = modelNode.GetPropertyBagValue(DefaultModelNodePropertyBagValue.Sys.IncrementalProvision.PersistenceStorageModelId); if (modelIdProperty == null) { throw new SPMeta2Exception("IncrementalProvisionModelId is not set. Either clean PersistenceStorages and handle model hash persistence manually or set .PersistenceStorageModelId"); } var modelId = modelIdProperty; var objectId = string.Format("{0}.{1}", DefaultPersistenceModelIdPrefix, modelId); var serializer = ServiceContainer.Instance.GetService <DefaultXMLSerializationService>(); serializer.RegisterKnownTypes(new[] { typeof(ModelHash), typeof(ModelNodeHash) }); foreach (var storage in storages) { TraceService.Information(0, string.Format("Restoring model hash with object id:[{0}] using storage impl [{1}]", objectId, storage.GetType())); var data = storage.LoadObject(objectId); if (data != null) { var dataString = Encoding.UTF8.GetString(data); var dataObject = serializer.Deserialize(typeof(ModelHash), dataString) as ModelHash; if (dataObject != null) { PreviousModelHash = dataObject; TraceService.Information(0, string.Format("Restored model hash with object id:[{0}] using storage impl [{1}]", objectId, storage.GetType())); break; } } else { TraceService.Information(0, string.Format("Restored model hash with object id:[{0}] using storage impl [{1}]", objectId, storage.GetType())); } } TraceService.Information(0, string.Format("Coudn't restore model hash with object id:[{0}]. Either first provision is user or storage is wrong.", objectId)); } else { TraceService.Information(0, "Model hash restore: can't find any persistence storage impl in Configuration.PersistenceStorages. Assuming manual model hash management is used"); } }
protected override void OnBeforeDeployModelNode(object modelHost, ModelNode modelNode) { // temporary measure // we need to restoreoriginal value of .RequireSelfProcessing to avoid any model changes // set 'ProcessedRequireSelfProcessingValue' in property bag for the further OriginalRequireSelfProcessingValue = modelNode.Options.RequireSelfProcessing; // lookup node and definition in model state // mark as modelNode.Options.RequireSelfProcessing true/false based on state var currentModelNode = modelNode; var currentDefinition = modelNode.Value; var prevModelHash = GetPreviousModelHash(); var isSingleIdentity = IsSingletonIdentityDefinition(currentDefinition); if (isSingleIdentity) { TraceService.InformationFormat(0, "Detected singleton definition [{0}]. Incremental update for such definitions isn't supported yet. Skipping.", currentDefinition); return; } else { TraceService.InformationFormat(0, "Calculating hashes for node and definition:[{0}]", currentDefinition); } //var currentNodeHashHash = HashService.GetHashCode(currentModelNode); var currentDefinitionHash = GetHashString(currentDefinition); var currentDefinitionIdentityKey = GetDefinitionIdentityKey(currentDefinition); var currentDefinitionIdentityHash = GetHashString(currentDefinitionIdentityKey); var currentDefinitionFullPath = GetDefinitionFullPath(false); var currentDefinitionFullPathHash = GetDefinitionFullPath(true); //TraceService.InformationFormat(0, " -node hash:[{0}]", currentNodeHashHash); TraceService.InformationFormat(0, " - definition hash:[{0}]", currentDefinitionHash); TraceService.InformationFormat(0, " - definition full path:[{0}]", currentDefinitionFullPath); TraceService.InformationFormat(0, " - definition full path hash:[{0}]", currentDefinitionFullPathHash); var prevModeNodeHashes = prevModelHash.ModelNodes .Where(h => h.DefinitionFullPathHash == currentDefinitionFullPathHash); // same definition is added multiple times // this could be // - toggling, such as feature activation toggling // - intentional toggling of the field or something // - intentional adding definition twice // we don't change anyting with the yet preferring to skip incremental provision detection if (prevModeNodeHashes.Count() > 1) { TraceService.InformationFormat(0, "Found more than one previous model node by path hash:[{0}]", currentDefinitionFullPathHash); TraceService.Information(0, "Not changing anything, incremental provision can't detect right path to change here."); IgnoredModelNodes.Add(currentModelNode); return; } var prevModeNodeHash = prevModeNodeHashes.FirstOrDefault(); if (prevModeNodeHash != null) { TraceService.InformationFormat(0, "Found previous model node by path hash:[{0}]", currentDefinitionFullPathHash); if (prevModeNodeHash.DefinitionHash != currentDefinitionHash) { TraceService.Information(0, "Definition hashes don't macth. Setting .Options.RequireSelfProcessing = true if it's not."); if (!modelNode.Options.RequireSelfProcessing) { modelNode.Options.RequireSelfProcessing = true; } } else { TraceService.Information(0, "Definition hashes match. Setting .Options.RequireSelfProcessing = false."); modelNode.Options.RequireSelfProcessing = false; } } else { TraceService.InformationFormat(0, "Cannot find previous model hash. Leaving .Options.RequireSelfProcessing as it is:[{0}]", currentModelNode.Options.RequireSelfProcessing); } }
public override void DeployModel(object modelHost, DefinitionBase model) { if (!(modelHost is SiteModelHost || modelHost is ListModelHost)) { throw new ArgumentException("modelHost needs to be SiteModelHost/ListModelHost instance."); } CurrentSiteModelHost = modelHost as SiteModelHost; TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Casting field model definition"); var fieldModel = model.WithAssertAndCast <FieldDefinition>("model", value => value.RequireNotNull()); Field currentField = null; ClientRuntimeContext context = null; InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, Object = null, ObjectType = GetTargetFieldType(fieldModel), ObjectDefinition = model, ModelHost = modelHost }); InvokeOnModelEvent <FieldDefinition, Field>(currentField, ModelEventType.OnUpdating); if (modelHost is SiteModelHost) { var siteHost = modelHost as SiteModelHost; context = siteHost.HostSite.Context; currentField = DeploySiteField(siteHost as SiteModelHost, fieldModel); } else if (modelHost is ListModelHost) { var listHost = modelHost as ListModelHost; context = listHost.HostList.Context; currentField = DeployListField(modelHost as ListModelHost, fieldModel); } object typedField = null; // emulate context.CastTo<>() call for typed field type if (GetTargetFieldType(fieldModel) != currentField.GetType()) { var targetFieldType = GetTargetFieldType(fieldModel); TraceService.InformationFormat((int)LogEventId.ModelProvisionCoreCall, "Calling context.CastTo() to field type: [{0}]", targetFieldType); var method = context.GetType().GetMethod("CastTo"); var generic = method.MakeGenericMethod(targetFieldType); typedField = generic.Invoke(context, new object[] { currentField }); } InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = typedField ?? currentField, ObjectType = GetTargetFieldType(fieldModel), ObjectDefinition = model, ModelHost = modelHost }); InvokeOnModelEvent <FieldDefinition, Field>(currentField, ModelEventType.OnUpdated); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "UpdateAndPushChanges(true)"); currentField.UpdateAndPushChanges(true); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()"); context.ExecuteQueryWithTrace(); }