msgraph-sdk-dotnet
msgraph-sdk-dotnet copied to clipboard
Create a new interface ICollectionRequest<TEntity>
It be nice if there would be a class like ICollectionRequest<TEntity>
which would define the default methods like
- GetAsync
- Expand
- Filter
- OrderBy
- Select
- Skip
- Top
This interface sould be added to all CollectionRequest classes like IGraphServiceUsersCollectionRequest
This would it make much easier to make some generic classes to work with Microsoft Graph.
The reason why we wouldn't set all of the potential methods on a request object is that there are capabilities that aren't supported on a particular request. We have backlog work for making our code file generator respect these capability restrictions.
This does bring up an interesting point around having basic OData functionality supported for an arbitrary request, especially ones that aren't generated.
How about an Interface for each (or related) methods?
Something like ICollectionGetRequest<TEntity>
for the GetAsync-method or ICollectionFilterRequest<TEntity>
for the Filter-method?
When will the code generator respect those capability restrictions?
Per capability interface is an interesting idea versus including a capability set on a single interface as we currently have. It would require a rewrite of our templates. How would you use these proposed interfaces?
The capability restriction work is tentatively scheduled for starting in the next 6 months. We are getting enough of a critical mass of capability metadata to make the effort worthwhile.
I would prefer a model similar to Linq where the OData capabilities are separate methods, over an interface for each capability as suggested above.
Ideally, the methods exist only on *Collection request builders, as the capability methods have no meaning on a call that returns a single entity.
(Extra points to the service owners who annotate their collections with supported capabilities so we don't have to guess. ;) )
And I would expect to specify those capability methods before the call to Request, which (at least to me) indicates it happens on the server.
For example:
var users = await graphClient
.Users
.OrderByDesc("displayName")
.Top(3)
.Request()
.GetAsync();
Both solutions would have their justification.
I would use it like that:
protected async Task<IList<TEntity>> ListAsync<TEntity, TEntityCollectionRequest>(TEntityCollectionRequest request)
where TEntity : Entity
where TEntityCollectionRequest : ICollectionGetRequest<TEntity>
{
IList<TEntity> entities = new List<TEntity>();
try
{
ICollectionPage<TEntity> collectionPage = await request.GetAsync();
PageIterator<TEntity> entityPageIterator = PageIterator<TEntity>.CreatePageIterator(
GraphServiceClient,
collectionPage,
entity => { entities.Add(entity); return true; });
await entityPageIterator.IterateAsync();
}
catch (Exception ex)
{
entities = null;
Logger.LogError(ex, $"Couldn't list '{typeof(TEntity)}'");
}
return entities;
}
Call:
public Task<IList<User>> ListUsersAsync()
{
return ListAsync<User>(GraphServiceClient.Users.Request());
}
This will likely be addressed in https://github.com/microsoft/kiota
@MIchaelMainer Will Kiota be integrated into the default Microsoft.Graph package? If yes, when will this happen?
@habex-ch Kiota will be the next generation code generator for creating the code files in Microsoft.Graph. We will refactor our code generation outputs so that it makes more sense. When exactly that happens for .NET is not yet defined.
closing this out as we are onto V5 and this should be addressed.