Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CmdLets for PowerShellCore - Xrm.Framework.CI.PowerShellCore.Cmdlets #327

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Xrm.Framework.CI.Common
{
public interface IReflectionLoader
{
void Initialise(string assemblyPath, string attributeClassName);
List<Dictionary<string, object>> Constructors { get; set; }
List<string> ClassNames { get; }
string AssemblyName { get; }
}

public class ReflectionLoader : IReflectionLoader
{
#region Members and Constructors
public List<Dictionary<string, object>> Constructors { get; set; }
public List<string> ClassNames { get; private set; }
public string AssemblyName { get; private set; }
private System.Reflection.Assembly _assembly;
private string CustomAttributeClassName { get; set; }

public ReflectionLoader()
{
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve +=
new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
Constructors = null;
ClassNames = null;

}
#endregion

public void Initialise(string assemblyPath, string attributeClassName)
{
CustomAttributeClassName = attributeClassName;
AssemblyName = LoadAssemblyForReflection(assemblyPath);
ClassNames = GetClassesUsingCustomAttribute(attributeClassName);
InitialiseConstructors();
}

#region Private Methods
private ConstructorInfo MatchAttributesToConstructor(ICollection<CustomAttributeTypedArgument> customAttributes,
string className, string attributeClassName)
{
var contenders = GetConstructorInfos(attributeClassName, customAttributes.Count);
var calledConstructor = GetCustomAttributeData(className, attributeClassName);
var constructorArgs = calledConstructor.ConstructorArguments.Select(ca => ca.ArgumentType).ToList();

foreach (var contender in contenders)
{
var paramTypes = contender.GetParameters().Select(p => p.ParameterType).ToList();
if (constructorArgs.SequenceEqual(paramTypes))
return contender;
}
return null;
}

private string LoadAssemblyForReflection(string assemblyPath)
{
_assembly = System.Reflection.Assembly.LoadFrom(assemblyPath);
return _assembly.ManifestModule.Name;
}

private CustomAttributeData GetCustomAttributeData(string className, string attributeClassName)
{
return CustomAttributeData.GetCustomAttributes(GetType(className)).First(
c => c.AttributeType == GetType(attributeClassName));
}

private System.Type GetType(string name)
{
return _assembly.GetType(name);
}

private List<ConstructorInfo> GetConstructorInfos(string className)
{
var t = GetType(className);
return t.GetConstructors().ToList();
}

private List<ConstructorInfo> GetConstructorInfos(string className, int parameterCount)
{
return (from x in GetConstructorInfos(className)
where x.GetParameters().ToList().Count == parameterCount
select x).ToList();
}

private void InitialiseConstructors()
{
Constructors = new List<Dictionary<string, object>>();
foreach (var pluginClass in ClassNames)
{
var constructorArgs = GetCustomAttributeData(pluginClass, CustomAttributeClassName).ConstructorArguments;
var constructorParameters = MatchAttributesToConstructor(
constructorArgs, pluginClass, CustomAttributeClassName).GetParameters();

var argDictionary = new Dictionary<string, object>();
for (var i = 0; i < constructorArgs.Count; i++)
{
argDictionary.Add(constructorParameters[i].Name, constructorArgs[i].Value);
}
Constructors.Add(argDictionary);
}
}

private List<string> GetClassesUsingCustomAttribute(string customAttributeClassName)
{
var allTypes = _assembly.GetTypes();
return (from t in allTypes let ca = t.GetCustomAttributes().ToList()
where ca.FirstOrDefault(x => x.GetType().FullName == customAttributeClassName) != null
&& t.FullName != customAttributeClassName
select t.FullName).ToList();
}

private System.Reflection.Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Xrm.Framework.CI.PowerShell.Cmdlets.Common
{
public class XrmSolutionInfo
{
public string UniqueName { get; set; }
public string Version { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="utf-8"?>
<Config xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AudibleCompletionNotification>true</AudibleCompletionNotification>
<CrmSvcUtilRelativePath>DLaB.EarlyBoundGenerator\crmsvcutil.exe</CrmSvcUtilRelativePath>
<IncludeCommandLine>false</IncludeCommandLine>
<MaskPassword>true</MaskPassword>
<SettingsVersion>1.2019.10.27</SettingsVersion>
<Version>1.2020.10.2</Version>
<ExtensionConfig>
<ActionPrefixesWhitelist />
<ActionsWhitelist />
<ActionsToSkip>msdyn_getsifeatureconfiguration|
retrieveappsetting|
retrieveappsettinglist|
saveappsetting</ActionsToSkip>
<AddDebuggerNonUserCode>false</AddDebuggerNonUserCode>
<AddNewFilesToProject>false</AddNewFilesToProject>
<AddOptionSetMetadataAttribute>true</AddOptionSetMetadataAttribute>
<CreateOneFilePerAction>false</CreateOneFilePerAction>
<CreateOneFilePerEntity>false</CreateOneFilePerEntity>
<CreateOneFilePerOptionSet>false</CreateOneFilePerOptionSet>
<DeleteFilesFromOutputFolders>false</DeleteFilesFromOutputFolders>
<EntitiesToSkip />
<EntitiesWhitelist>asyncoperation|
bulkdeleteoperation|
connectionreference|
dependency|
duplicaterule|
environmentvariabledefinition|
environmentvariablevalue|
importjob|
pluginassembly|
plugintype|
sdkmessage|
sdkmessagefilter|
sdkmessageprocessingstep|
sdkmessageprocessingstepimage|
serviceendpoint|
solution|
solutioncomponent|
solutionhistorydata|
systemform|
systemuser|
webresource|
workflow</EntitiesWhitelist>
<EntityAttributeSpecifiedNames />
<EntityPrefixesToSkip />
<EntityPrefixesWhitelist />
<GenerateActionAttributeNameConsts>false</GenerateActionAttributeNameConsts>
<GenerateAttributeNameConsts>false</GenerateAttributeNameConsts>
<GenerateAnonymousTypeConstructor>false</GenerateAnonymousTypeConstructor>
<GenerateConstructorsSansLogicalName>false</GenerateConstructorsSansLogicalName>
<GenerateEntityRelationships>false</GenerateEntityRelationships>
<GenerateEntityTypeCode>false</GenerateEntityTypeCode>
<GenerateEnumProperties>true</GenerateEnumProperties>
<GenerateOnlyReferencedOptionSets>true</GenerateOnlyReferencedOptionSets>
<GenerateOptionSetMetadataAttribute>true</GenerateOptionSetMetadataAttribute>
<InvalidCSharpNamePrefix>_</InvalidCSharpNamePrefix>
<MakeAllFieldsEditable>false</MakeAllFieldsEditable>
<MakeReadonlyFieldsEditable>false</MakeReadonlyFieldsEditable>
<MakeResponseActionsEditable>false</MakeResponseActionsEditable>
<LocalOptionSetFormat>{0}_{1}</LocalOptionSetFormat>
<OptionSetLanguageCodeOverride
xsi:nil="true" />
<OptionSetPrefixesToSkip />
<OptionSetsToSkip />
<ProjectNameForEarlyBoundFiles />
<PropertyEnumMappings />
<ReadSerializedMetadata>false</ReadSerializedMetadata>
<RemoveRuntimeVersionComment>false</RemoveRuntimeVersionComment>
<ReplaceOptionSetPropertiesWithEnum>false</ReplaceOptionSetPropertiesWithEnum>
<SerializeMetadata>false</SerializeMetadata>
<UnmappedProperties>duplicaterule:BaseEntityTypeCode,MatchingEntityTypeCode|
invoicedetail:InvoiceStateCode|
leadaddress:AddressTypeCode,ShippingMethodCode|
organization:CurrencyFormatCode,DateFormatCode,TimeFormatCode,WeekStartDayCode|
quote:StatusCode|
quotedetail:QuoteStateCode|
salesorderdetail:SalesOrderStateCode</UnmappedProperties>
<UseDeprecatedOptionSetNaming>false</UseDeprecatedOptionSetNaming>
<UseTfsToCheckoutFiles>false</UseTfsToCheckoutFiles>
<WaitForAttachedDebugger>false</WaitForAttachedDebugger>
</ExtensionConfig>
<ExtensionArguments>
<Argument>
<SettingType>Actions</SettingType>
<Name>codecustomization</Name>
<Value>DLaB.CrmSvcUtilExtensions.Action.CustomizeCodeDomService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Actions</SettingType>
<Name>codegenerationservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.Action.CustomCodeGenerationService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Actions</SettingType>
<Name>codewriterfilter</Name>
<Value>DLaB.CrmSvcUtilExtensions.Action.CodeWriterFilterService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Actions</SettingType>
<Name>metadataproviderservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.BaseMetadataProviderService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Entities</SettingType>
<Name>codecustomization</Name>
<Value>DLaB.CrmSvcUtilExtensions.Entity.CustomizeCodeDomService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Entities</SettingType>
<Name>codegenerationservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.Entity.CustomCodeGenerationService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Entities</SettingType>
<Name>codewriterfilter</Name>
<Value>DLaB.CrmSvcUtilExtensions.Entity.CodeWriterFilterService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Entities</SettingType>
<Name>namingservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.NamingService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>Entities</SettingType>
<Name>metadataproviderservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.Entity.MetadataProviderService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>OptionSets</SettingType>
<Name>codegenerationservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.OptionSet.CustomCodeGenerationService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>OptionSets</SettingType>
<Name>codewriterfilter</Name>
<Value>DLaB.CrmSvcUtilExtensions.OptionSet.CodeWriterFilterService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>OptionSets</SettingType>
<Name>namingservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.NamingService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>OptionSets</SettingType>
<Name>metadataproviderservice</Name>
<Value>DLaB.CrmSvcUtilExtensions.BaseMetadataProviderService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
<Argument>
<SettingType>OptionSets</SettingType>
<Name>codecustomization</Name>
<Value>DLaB.CrmSvcUtilExtensions.OptionSet.CustomizeCodeDomService,DLaB.CrmSvcUtilExtensions</Value>
</Argument>
</ExtensionArguments>
<UserArguments>
<Argument>
<SettingType>Actions</SettingType>
<Name>generateActions</Name>
</Argument>
<Argument>
<SettingType>Actions</SettingType>
<Name>out</Name>
<Value>CrmSvcUtil Ref\Actions.cs</Value>
</Argument>
<Argument>
<SettingType>All</SettingType>
<Name>namespace</Name>
<Value>Xrm.Framework.CI.Common.Entities</Value>
</Argument>
<Argument>
<SettingType>Entities</SettingType>
<Name>out</Name>
<Value>Entities.cs</Value>
</Argument>
<Argument>
<SettingType>Entities</SettingType>
<Name>servicecontextname</Name>
<Value>CIContext</Value>
</Argument>
<Argument>
<SettingType>OptionSets</SettingType>
<Name>out</Name>
<Value>OptionSets.cs</Value>
</Argument>
</UserArguments>
<WorkflowlessActions>msdyn_GetSIFeatureConfiguration|
RetrieveAppSetting|
RetrieveAppSettingList|
SaveAppSetting</WorkflowlessActions>
</Config>
Loading