Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Throw a better exception when the user didn't add the MVC services #1045

Closed
wants to merge 4 commits into from

Conversation

sornaks
Copy link

@sornaks sornaks commented Aug 20, 2014

Issue #347 - Added a check in UseMvc() to verify if AddMvc() was called before.
Added functional tests for the same.

// Verify if AddMvc was done before calling UseMvc
// Try to get 2 sample services. If it returns null then AddMvc was not called.
if(app.ApplicationServices.GetServiceOrNull(typeof(IActionDescriptorsCollectionProvider)) == null ||
app.ApplicationServices.GetServiceOrNull(typeof(IInlineConstraintResolver)) == null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to define a transient marker service specifically for this purpose so there are no wierd interactions.

For instance IActionDescriptorsCollectionProvider might have another dependencies that also now get eagerly instantiated. Even if this is not a problem now, it might introduce a bug later if we change the implementation - or worse it could break a user-defined implementation.

Also IInlineConstraintResolver is defined by routing, and has its own extension methods in routing to add it if you're not using MVC, leading to a false positive.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. This is a good idea. Will implement this in the next iteration.

Would like to point out one corner case though - If the user decides to add all the services one by one manually (for some reason) then he might miss this service (which we are going to specifically use to validate AddMvc()).

@rynowak
Copy link
Member

rynowak commented Aug 20, 2014

@@ -24,6 +25,14 @@ public static IBuilder UseMvc([NotNull] this IBuilder app)

public static IBuilder UseMvc([NotNull] this IBuilder app, [NotNull] Action<IRouteBuilder> configureRoutes)
{
// Verify if AddMvc was done before calling UseMvc
// Try to get 2 sample services. If it returns null then AddMvc was not called.
if(app.ApplicationServices.GetServiceOrNull(typeof(IActionDescriptorsCollectionProvider)) == null ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after if; have you run Stylecop?

@sornaks
Copy link
Author

sornaks commented Aug 21, 2014

Have updated the PR. Please have a look..

@rynowak
Copy link
Member

rynowak commented Aug 21, 2014

@davidfowl @Eilon

Except it's not IAppBuilder.UseServices

Yeah that's what I mean about getting more feedback. It's an extension method, but I dunno if using the full name of the extension methods makes it more or less clear what to do.

using System;
using Microsoft.Framework.DependencyInjection;

namespace Microsoft.AspNet.Mvc.Core
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Microsoft.AspNet.Mvc.Internal

@sornaks
Copy link
Author

sornaks commented Aug 21, 2014

Updated the PR.. Please have a look..

/// </summary>
/// <param name="services">The list of services.</param>
/// <param name="serviceType">The type of service which needs to be searched for.</param>
public static object ThrowIfServiceDoesNotExist(IServiceProvider services)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably be something like ThrowIfMvcNotRegistered and return void.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have something to return so that this can be properly Unit Tested.. If its void, how do I write a positive test case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just has to not-throw. Assert.DoesNotThrow(...)

@rynowak
Copy link
Member

rynowak commented Aug 21, 2014

{
/// <summary>
/// Throws InvalidOperationException when the given type of service is not present
/// in the list of services.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, doc is wrong here

@sornaks
Copy link
Author

sornaks commented Aug 21, 2014

Updated..

/// This is a Marker class which is used to determine if all the services were added
/// to when Mvc is loaded.
/// </summary>
public class MvcMarkerService
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mark it sealed. There's no utility in modifying this type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't something we're spending time on in general. It's part of the public by default, unsealed by default principle.

@pranavkm
Copy link
Contributor

:shipit: from me.

@rynowak
Copy link
Member

rynowak commented Aug 21, 2014

:shipit: from me

@sornaks
Copy link
Author

sornaks commented Aug 21, 2014

Checked in. 791518d

@sornaks sornaks closed this Aug 21, 2014
@sornaks sornaks deleted the UseMvcError branch August 21, 2014 21:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants