Closed teh173 closed 8 months ago
The file size is a big issue for me at the moment. I had to go back to 4.x. I can't upload any signal file over 25mb to the server, right now this dll is 36mb.
I hope this is a fast fix so I can go to 5.x
Same for Microsoft.Graph.xml
v4.6 - 29.7 MB (31,194,770 bytes)
v5.1 - 61.9 MB (64,972,960 bytes)
I suspect that very long namespaces have effect on the size of dll and xml.
Example:
v5 - Microsoft.Graph.Drives.Item.Items.Item.Analytics.ItemActivityStats.Item.Activities.Item.ItemActivityItemRequestBuilder
8x times word Item
in one namespace is really weird.
v4 - Microsoft.Graph.IItemActivityRequestBuilder.Request
The issue still not resolved even after upgrading to version 5.2
Good Morning,
Is there an update on this? I'm unable to switch to this until the dll size issue is fixed.
I just tried upgrading to 5.3.0 and it still 36mb. There is no way for me to around the 25mb file limit. Can we please address this issue.
I just tried upgrading to 5.3.0 and it still 36mb. There is no way for me to around the 25mb file limit. Can we please address this issue.
The issue still not resolved even after upgrading to version 5.2
Tested version 5.4 Not yet fixed.
Do we have a status update on this? It would be really nice to go to graph 5.0.
Thank you
Is there any update on the size issue?
Do we have any update on why the file size is so large and a ETA of it being fixed?
@silentdevnull https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/1874 Looks like the target version with a fix is v6.
From my investigation, there is a lot of duplicated classes with the same name but under different namespaces. I've comparing v4.54 and v5.9
version 4.54 In version 4.54 there is around 8199 classes and the size of MicrosoftGraph.dll is around 11 MB
version 5.9.0 In version 5.9.0 there is around 28799 classes and the size of MicrosoftGraph.dll is around 34 MB. If classes are grouped by a name (not a full name) then the number of classes is around 8196.
The table bellow shows classes which are in more than 50 different namespaces.
class name | number |
---|---|
CountRequestBuilder | 1492 |
CountRequestBuilderGetRequestConfiguration | 1491 |
CountRequestBuilderGetQueryParameters | 1482 |
DeltaRequestBuilder | 120 |
DeltaResponse | 119 |
DeltaRequestBuilderGetQueryParameters | 119 |
DeltaRequestBuilderGetRequestConfiguration | 119 |
ContentRequestBuilder | 111 |
ContentRequestBuilderGetRequestConfiguration | 111 |
ContentRequestBuilderPutRequestConfiguration | 111 |
SetRequestBuilder | 108 |
SetRequestBuilderGetQueryParameters | 108 |
SetRequestBuilderGetRequestConfiguration | 108 |
SingleValueExtendedPropertiesRequestBuilder | 71 |
SingleValueLegacyExtendedPropertyItemRequestBuilder | 71 |
MultiValueExtendedPropertiesRequestBuilder | 71 |
MultiValueLegacyExtendedPropertyItemRequestBuilder | 71 |
SingleValueExtendedPropertiesRequestBuilderGetQueryParameters | 71 |
SingleValueExtendedPropertiesRequestBuilderGetRequestConfiguration | 71 |
SingleValueExtendedPropertiesRequestBuilderPostRequestConfiguration | 71 |
SingleValueLegacyExtendedPropertyItemRequestBuilderDeleteRequestConfiguration | 71 |
SingleValueLegacyExtendedPropertyItemRequestBuilderGetQueryParameters | 71 |
SingleValueLegacyExtendedPropertyItemRequestBuilderGetRequestConfiguration | 71 |
SingleValueLegacyExtendedPropertyItemRequestBuilderPatchRequestConfiguration | 71 |
MultiValueExtendedPropertiesRequestBuilderGetQueryParameters | 71 |
MultiValueExtendedPropertiesRequestBuilderGetRequestConfiguration | 71 |
MultiValueExtendedPropertiesRequestBuilderPostRequestConfiguration | 71 |
MultiValueLegacyExtendedPropertyItemRequestBuilderDeleteRequestConfiguration | 71 |
MultiValueLegacyExtendedPropertyItemRequestBuilderGetQueryParameters | 71 |
MultiValueLegacyExtendedPropertyItemRequestBuilderGetRequestConfiguration | 71 |
MultiValueLegacyExtendedPropertyItemRequestBuilderPatchRequestConfiguration | 71 |
RefRequestBuilder | 69 |
ExtensionsRequestBuilder | 66 |
ExtensionItemRequestBuilder | 66 |
ExtensionsRequestBuilderGetQueryParameters | 66 |
ExtensionsRequestBuilderGetRequestConfiguration | 66 |
ExtensionsRequestBuilderPostRequestConfiguration | 66 |
ExtensionItemRequestBuilderDeleteRequestConfiguration | 66 |
ExtensionItemRequestBuilderGetQueryParameters | 66 |
ExtensionItemRequestBuilderGetRequestConfiguration | 66 |
ExtensionItemRequestBuilderPatchRequestConfiguration | 66 |
RelationsRequestBuilder | 60 |
RelationItemRequestBuilder | 60 |
ToTermRequestBuilder | 60 |
FromTermRequestBuilder | 60 |
RelationsRequestBuilderGetQueryParameters | 60 |
RelationsRequestBuilderGetRequestConfiguration | 60 |
RelationsRequestBuilderPostRequestConfiguration | 60 |
RelationItemRequestBuilderDeleteRequestConfiguration | 60 |
RelationItemRequestBuilderGetQueryParameters | 60 |
RelationItemRequestBuilderGetRequestConfiguration | 60 |
RelationItemRequestBuilderPatchRequestConfiguration | 60 |
ToTermRequestBuilderGetQueryParameters | 60 |
ToTermRequestBuilderGetRequestConfiguration | 60 |
FromTermRequestBuilderGetQueryParameters | 60 |
FromTermRequestBuilderGetRequestConfiguration | 60 |
CreateUploadSessionPostRequestBody | 55 |
CreateUploadSessionRequestBuilder | 55 |
ParentNotebookRequestBuilder | 55 |
CreateUploadSessionRequestBuilderPostRequestConfiguration | 55 |
ParentNotebookRequestBuilderGetQueryParameters | 55 |
ParentNotebookRequestBuilderGetRequestConfiguration | 55 |
AttachmentsRequestBuilder | 53 |
AttachmentsRequestBuilderGetQueryParameters | 53 |
AttachmentsRequestBuilderGetRequestConfiguration | 53 |
AttachmentsRequestBuilderPostRequestConfiguration | 53 |
ForwardPostRequestBody | 50 |
ForwardRequestBuilder | 50 |
AttachmentItemRequestBuilder | 50 |
ForwardRequestBuilderPostRequestConfiguration | 50 |
AttachmentItemRequestBuilderDeleteRequestConfiguration | 50 |
AttachmentItemRequestBuilderGetQueryParameters | 50 |
AttachmentItemRequestBuilderGetRequestConfiguration | 50 |
Why to have more than 1000 classes with the same name and the same implementation?
snippet
var graphAssembly = Assembly.Load(AssemblyName.GetAssemblyName("Microsoft.Graph.dll"));
var types = graphAssembly.GetTypes();
var classes = new List<(string name, string fullname)>();
foreach (var tc in types)
{
if (tc.IsClass && tc.FullName.StartsWith("Microsoft.Graph"))
{
classes.Add((tc.Name, tc.FullName));
}
}
var groups = classes.GroupBy(x => x.name).OrderByDescending(x => x.Count()).ToList();
@silentdevnull #1874 Looks like the target version with a fix is v6.
Thank you for the information.
I can't believe the are going to not fix it in the current version as this a big issue.
I hope version 4 doesn't break because if it does, I'm screwed big time. I can't update an of my application to 5.
We recently moved onto the graph API due to the deprecation/turned off the ability to use EWS with modern auth. We're just finding this Microsoft.Graph.dll file is bigger than the entirety of some of our applications (wpf based). It's extremely wasteful for client applications that run on low spec pcs.
This has a huge impact on first load time after building a project. I have a web server which previously would take 9s after build to load the first page. Adding this package it takes 30s...3 times longer!
Edit: I spent the last couple of days studying the source code and implementing a "thin" client alternative, based mostly on copying the models out of the SDKs source and then using the Microsoft.Graph.Core
package directly.
For anyone who's interested, I put together a [github gist])https://gist.github.com/d-a-s/bea2792daa8f6e1b835696dfc487165f). It's a simplified/sanitized version of the code I ended up with.
Please reduce the size of the Microsoft.Graph.dll. My .Net 7 app publish file size is ~10Mb without Microsoft Graph and after adding it and build in R2R, the size is now 180Mb.
Yes, this single assembly blows up applications by a ridiculous amount.
Yes, the issue is that there is only one single assembly that contains builders for thousands endpoints. Real use case is that an app is calling only a small subset of endpoints, so it uses < 1% of builders and endpoints.
Since all builders are generated by Kiota, it should be possible to split up Microsoft.Graph
project into small ones. Each project will generate own NuGet package and developers can reference only one small NuGet package.
Example:
src\Microsoft.Graph\Generated\RoleManagement will have NuGet Microsoft.Graph.RoleManagement
with RoleManagementServiceClient
similar to the current GraphServiceClient
and BaseGraphServiceClient
// <auto-generated/>
using Microsoft.Graph.RoleManagement;
...
namespace Microsoft.Graph {
/// <summary>
/// The main entry point of the SDK, exposes the configuration and the fluent API.
/// </summary>
public class RoleManagementBaseGraphServiceClient : BaseRequestBuilder {
/// <summary>Provides operations to manage the roleManagement singleton.</summary>
public RoleManagementRequestBuilder RoleManagement { get =>
new RoleManagementRequestBuilder(PathParameters, RequestAdapter);
}
/// <summary>
/// Instantiates a new RoleManagementBaseGraphServiceClient and sets the default values.
/// </summary>
/// <param name="backingStore">The backing store to use for the models.</param>
/// <param name="requestAdapter">The request adapter to use to execute the requests.</param>
public RoleManagementBaseGraphServiceClient(IRequestAdapter requestAdapter, IBackingStoreFactory backingStore = default) : base(requestAdapter, "{+baseurl}", new Dictionary<string, object>()) {
ApiClientBuilder.RegisterDefaultSerializer<JsonSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<TextSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<FormSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultSerializer<MultipartSerializationWriterFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<JsonParseNodeFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<TextParseNodeFactory>();
ApiClientBuilder.RegisterDefaultDeserializer<FormParseNodeFactory>();
if (string.IsNullOrEmpty(RequestAdapter.BaseUrl)) {
RequestAdapter.BaseUrl = "https://graph.microsoft.com/v1.0";
}
PathParameters.TryAdd("baseurl", RequestAdapter.BaseUrl);
RequestAdapter.EnableBackingStore(backingStore);
}
}
@MartinM85 - You can use Kiota to generate an SDK for Graph that includes whatever endpoints you wish.
@pschaeflein Sure, I can generate a SDK for Graph API with Kiota by myself, but the whole process is quite complicated. Metadata for OpenAPI spec are preprocessed several times, but it's a good idea. I can imagine some tool where devs check which endpoints should be included into Graph API SDK, select language(s), etc.
Hi everyone, This thread was brought to my attention during the Microsoft MVP summit this week. Apologies for the delays in getting a proper reply.
I'll write down a lengthy explanations of the situation here and hopefully it answers most questions.
Microsoft Graph is an extremely large API and packaging any client for it has always, and will remain a challenge. It's a trade-off between getting access to as many capabilities as possible and keeping size under control. We acknowledge that size can be a limiting factor and/or degrade the developer/end user experience.
No application needs all Graph operations and endpoints, while a pre-packaged SDK makes things straightforward to discover and consume, it brings its trade-off. For scenarios that are constrained on size, we recommend that you explore generating your own client with kiota. You'll get the same exact experience (models, fluent API, etc...) but for only the operations your application needs, reducing the footprint drastically. On the self serve story, the main gap we've had to date is the lack of documentation. This is something we're starting to address https://github.com/microsoftgraph/microsoft-graph-docs/pull/23917
We've worked with the dotnet team to enable proper AOT support. If you haven't explored that aspect, and you don't want to switch to a self-served client, you should try AOT, which among other things tree-shakes the assemblies. In a containerized scenario the dotnet team went from ~350+MB down to ~30MB (trimming + changing base image).
We've changed the way we project the code where we could without introducing a breaking change. That already resulted in a size reduction (I don't have the numbers handy anymore, but can look them up if anyone is interested)
One thing that was missed before GA, is to NOT generate code for /me, and bind the path to the same code as /users/id. The user object ties in to a lot of the API surface, and this "duplication" results in about 30% size waste. https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/1874 We also had ambiguous naming convention issues we've had to fix, and add backward compatible obsolete symbols, this wastes another 10 % (so 37% total). We're planning to clean all this up during the next major release as all these things represent breaking changes. We don't have a timeline for that yet.
This is simply a naming pattern when indexing into collections. Since Graph is designed with a lot of nested collections, it can lead to duplication. Is there any additional questions on that aspect?
This is a design choice, effectively each request builder is different from one another because the request body, response, operations, query parameters, etc... Can vary from one to another. They are used to build the fluent API experience. It just happens so Graph being based on odata conventions has a lot of naming repetition. I'm curious to why this is causing friction for you? The way this API is designed, there are only very rare cases where you should have to import them. Can you expand on why you believe this is an issue?
This is something we've talked about multiple times in the past. We've had to do it for TypeScript for example. But it adds a lot of complexity to the consumer of the packages and maintenance burden for us. We feel like dotnet is efficient enough to produce reasonably sized packages given the size of the API. And most scenarios that dotnet is used in are either not size constrained (server apps), or trimmed (AOT, etc...) for this investment to be worth the trade-off.
I hope this lengthy reply helps clarify a lot of the interrogations, please do not hesitate to follow-up on the points mentioned above.
Self-served clients
No application needs all Graph operations and endpoints, while a pre-packaged SDK makes things straightforward to discover and consume, it brings its trade-off. For scenarios that are constrained on size, we recommend that you explore generating your own client with kiota. You'll get the same exact experience (models, fluent API, etc...) but for only the operations your application needs, reducing the footprint drastically. On the self serve story, the main gap we've had to date is the lack of documentation. This is something we're starting to address https://github.com/microsoftgraph/microsoft-graph-docs/pull/23917
@baywet Could you please edit the link? It's linked to the old doc repository. New repo for doc is https://github.com/microsoftgraph/microsoft-graph-docs-contrib
Sorry about that. The page has since been published here don't hesitate to provide feedback!
Could Microsoft.Graph be modularised in the future? Currently, this dependency alone is doubling the application's footprint just to handle authorisation for me.
Describe the bug File size of Microsoft.Graph.dll seems bigger than it needs to be if I'm just using a few APIs from Graph. Can the Graph DLL be split up? Is there a simple way to leave things I don't need compiled out?
It's jumped massively with 5.0.
4.x:
5.x:
See also: https://github.com/microsoftgraph/msgraph-beta-sdk-dotnet/issues/500
Expected behavior Distributable size proportionate to need.