Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,10 @@ FakesAssemblies/
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
<<<<<<< HEAD
bower_components/
/output
=======

# Visual Studio 6 build log
*.plg
Expand Down Expand Up @@ -443,3 +447,4 @@ $RECYCLE.BIN/
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
>>>>>>> dev
40 changes: 39 additions & 1 deletion Templates/templates/CSharp/Requests/IMethodRequestBuilder.cs.tt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

var method = host.CurrentType.AsOdcmMethod();
var @namespace = method.Namespace.GetNamespaceName();
// Get navigation properties and methods of the return type if the method is composable.
var composableMethodNavigations = method.IsComposable ? method.GetComposableFunctionReturnTypeNavigations() : new List<OdcmProperty>();
var composableNavigationsInfo = composableMethodNavigations.GetAllNavigationPropertyInfo();
var composableMethodMethods = method.IsComposable ? method.GetComposableFunctionReturnTypeMethods() : new List<OdcmMethod>();
var composableMethodsInfo = composableMethodMethods.GetAllMethodsInfo(@namespace);

var optionTypeName = @namespace.GetCoreLibraryType("Option");

Expand All @@ -22,13 +27,46 @@ namespace <#=@namespace#>
/// <summary>
/// The interface I<#=requestBuilderType#>.
/// </summary>
public partial interface I<#=requestBuilderType#>
public partial interface I<#=requestBuilderType#> : IBaseRequestBuilder
{
/// <summary>
/// Builds the request.
/// </summary>
/// <param name="options">The query and header options for the request.</param>
/// <returns>The built request.</returns>
I<#=requestType#> Request(IEnumerable<<#=optionTypeName#>> options = null);
<#
// Add request builders for every function bound to the return type of this function.
if (composableMethodsInfo != null)
{
foreach (var m in composableMethodsInfo)
{
#>
/// <summary>
/// Gets the request builder for <#=m.RequestBuilderType#>.
/// </summary><#=m.ParameterComments#>
/// <returns>The <see cref="I<#=m.RequestBuilderType#>"/>.</returns>
I<#=m.RequestBuilderType#> <#=m.MethodName#>(<#=m.MethodParametersAsArguments#>);
<#
}
}
#>
<#
// Add request builders for every navigation property on the return type of this function.
if (composableNavigationsInfo != null)
{
foreach (var n in composableNavigationsInfo)
{
#>
/// <summary>
/// Gets the request builder for <#=n.Name#>.
/// <#=n.Description#>
/// </summary>
/// <returns>The <see cref="<#=n.ReturnInterfaceRequestBuilderName#>"/>.</returns>
<#=n.ReturnInterfaceRequestBuilderName#> <#=n.Name#> { get; }
<#
}
}
#>
}
}
100 changes: 58 additions & 42 deletions Templates/templates/CSharp/Requests/MethodRequestBuilder.cs.tt
Original file line number Diff line number Diff line change
Expand Up @@ -18,52 +18,19 @@ var baseMethodRequestBuilderTypeName = @namespace.GetCoreLibraryType("Base" + me
var iBaseClientTypeName = @namespace.GetCoreLibraryType("IBaseClient");
var optionTypeName = @namespace.GetCoreLibraryType("Option");

// Get navigation properties and methods of the return type if the method is composable.
var composableMethodNavigations = method.IsComposable ? method.GetComposableFunctionReturnTypeNavigations() : new List<OdcmProperty>();
var composableNavigationsInfo = composableMethodNavigations.GetAllNavigationPropertyInfo();
var composableMethodMethods = method.IsComposable ? method.GetComposableFunctionReturnTypeMethods() : new List<OdcmMethod>();
var composableMethodsInfo = composableMethodMethods.GetAllMethodsInfo(@namespace);

// Overloads are determined based on the name of method and the type of the binding parameter.
// There is no differentiation between an entity, and a collection of the same entities.
// This may cause issues in the future that would require changes.
var overloads = new List<OdcmMethod>();
overloads.Add(method);
overloads.AddRange(method.Overloads);

var methods = overloads
.Select(m =>
{
var parameters = m.Parameters
.Select(p =>
{
var type = p.Type.GetTypeString(@namespace);
var name = p.Name.ToLowerFirstChar();
var parameterName = p.Name.GetSanitizedParameterName();
var propertyName = p.Name.ToCheckedCase();

// Adds support for classes ending in "Request" that have been dismabiguated.
if (type.EndsWith("Request"))
{
type = String.Concat(type, "Object");
}
if (p.IsCollection)
{
type = string.Format("IEnumerable<{0}>", type);
}
else if (!p.Type.IsTypeNullable() && p.IsNullable)
{
type += "?";
}

return new { Type = type, Name = name, ParameterName = parameterName, PropertyName = propertyName, IsNullable = p.IsNullable };
})
.OrderBy(p => p.IsNullable ? 1 : 0);

var paramStrings = parameters.Select(p => string.Format(",\n {0} {1}", p.Type, p.ParameterName));
var paramComments = parameters.Select(p => string.Format("\n /// <param name=\"{0}\">A {0} parameter for the OData method call.</param>", p.ParameterName));

return new
{
Parameters = parameters,
ParametersAsArguments = string.Join("", paramStrings),
ParameterComments = string.Join("", paramComments),
};
});
var overloadMethodsInfo = overloads.GetAllMethodsInfo(@namespace);

#>

Expand All @@ -82,7 +49,7 @@ namespace <#=@namespace#>
// We only want to generate unique method signatures.
// We'll use the ParametersAsArguments to define the uniqueness of a method.
HashSet<string> uniqueMethods = new HashSet<string>();
foreach (var m in methods)
foreach (var m in overloadMethodsInfo)
{
// Only generate a unique method.
if (uniqueMethods.Add(m.ParametersAsArguments) == true)
Expand All @@ -105,8 +72,13 @@ foreach (var m in methods)
this.SetParameter("<#=p.Name#>", <#=p.ParameterName#>, <#=p.IsNullable.ToString().ToLowerInvariant()#>);
<#
}
if (method.IsFunction)
{
#>
this.SetFunctionParameters();
<#
}
#> }

<#
}
Expand All @@ -127,7 +99,7 @@ foreach (var m in methods)
{
HashSet<string> uniqueParameters = new HashSet<string>();

foreach (var m in methods)
foreach (var m in overloadMethodsInfo)
{
foreach (var p in m.Parameters)
{
Expand All @@ -148,5 +120,49 @@ foreach (var m in methods)
#>
return request;
}
<#
// Add request builders for every function bound to the return type of this function.
if (composableMethodsInfo != null)
{
foreach (var m in composableMethodsInfo)
{
#>
/// <summary>
/// Gets the request builder for <#=m.RequestBuilderType#>.
/// </summary><#=m.ParameterComments#>
/// <returns>The <see cref="I<#=m.RequestBuilderType#>"/>.</returns>
public I<#=m.RequestBuilderType#> <#=m.MethodName#>(<#=m.MethodParametersAsArguments#>)
{
return new <#=m.RequestBuilderType#>(
this.AppendSegmentToRequestUrl("<#=m.MethodFullName#>"),
this.Client<#=m.ParamArgsForConstructor#>);
}
<#
}
}
#>
<#
// Add request builders for every navigation property on the return type of this function.
if (composableNavigationsInfo != null)
{
foreach (var n in composableNavigationsInfo)
{
#>
/// <summary>
/// Gets the request builder for <#=n.Name#>.
/// <#=n.Description#>
/// </summary>
/// <returns>The <see cref="<#=n.ReturnInterfaceRequestBuilderName#>"/>.</returns>
public <#=n.ReturnInterfaceRequestBuilderName#> <#=n.Name#>
{
get
{
return new <#=n.ReturnClassRequestBuilderName#>(this.AppendSegmentToRequestUrl("<#=n.Segment#>"), this.Client);
}
}
<#
}
}
#>
}
}
52 changes: 52 additions & 0 deletions src/GraphODataTemplateWriter/CodeHelpers/CSharp/MethodInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Linq;

namespace Microsoft.Graph.ODataTemplateWriter.CodeHelpers.CSharp
{
/// <summary>
/// Contains the OData method information used in method request builders.
/// </summary>
public class MethodInfo
{
/// <summary>
/// Specifies the list of parameters in the method. Not used in the
/// creation of request builders for the methods bound to the return
/// type of this method.
/// </summary>
public IOrderedEnumerable<ParameterInfo> Parameters { get; set; }
/// <summary>
/// Specifies the parameter arguments to fill out the method constructor.
/// </summary>
public string ParametersAsArguments { get; set; }
/// <summary>
/// Specifies the parameter arguments to fill out the method signatures
/// for the request builders that call the methods bound to the return
/// type of this method.
/// </summary>
public string ParamArgsForConstructor { get; set; }
/// <summary>
/// Contains the parameter doc comments for both the overload and
/// the methods bound to the return type of this method.
/// </summary>
public string ParameterComments { get; set; }
/// <summary>
/// Specifies the request builder type for the methods bound to the
/// return type of this method.
/// </summary>
public string RequestBuilderType { get; set; }
/// <summary>
/// Specifies the method name for the methods bound to the return
/// type of this method. This is the same name as found in the CSDL.
/// </summary>
public string MethodName { get; set; }
/// <summary>
/// Specifies the fully qualified method name for the methods bound to
/// the return type of this method.
/// </summary>
public string MethodFullName { get; set; }
/// <summary>
/// Specifies the parameter arguments to fill out the method constructor
/// for the methods bound to the return type of this method.
/// </summary>
public string MethodParametersAsArguments { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace Microsoft.Graph.ODataTemplateWriter.CodeHelpers.CSharp
{
/// <summary>
/// Contains the navigation property information used in method request builders.
/// </summary>
public class NavigationPropertyInfo
{
/// <summary>
/// Specifies the name of the interface which is the property type.
/// </summary>
public string ReturnInterfaceRequestBuilderName { get; set; }
/// <summary>
/// Specifies the name of the returned request builder.
/// </summary>
public string ReturnClassRequestBuilderName { get; set; }
/// <summary>
/// Specifies the path segment for the navigation property.
/// </summary>
public string Segment { get; set; }
/// <summary>
/// Specfies the name of the navigation property which is the
/// name of the request builder property.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Doc comments
/// </summary>
public string Description { get; set; }
}
}
16 changes: 16 additions & 0 deletions src/GraphODataTemplateWriter/CodeHelpers/CSharp/ParameterInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Linq;

namespace Microsoft.Graph.ODataTemplateWriter.CodeHelpers.CSharp
{
/// <summary>
/// Contains the parameter details about an OData method.
/// </summary>
public class ParameterInfo
{
public string Type { get; set; }
public string Name { get; set; }
public string ParameterName { get; set; }
public string PropertyName { get; set; }
public bool IsNullable { get; set; }
}
}
Loading