-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Adding a way to initialize ServiceClient using provided HttpClient #2909
Conversation
shahabhijeet
commented
Mar 8, 2017
•
edited
Loading
edited
- Support for initializing ServiceClient using HttpClient
- Added tests using customized clients
- Added test for FakeClient
- Fixed failing Operational Insights tests
@@ -253,7 +269,7 @@ protected static HttpClientHandler CreateRootHandler() | |||
/// <summary> | |||
/// Gets the HttpClient used for making HTTP requests. | |||
/// </summary> | |||
public HttpClient HttpClient { get; protected set; } | |||
public virtual HttpClient HttpClient { get; protected set; } | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you consider this issue? http://stackoverflow.com/questions/119506/virtual-member-call-in-a-constructor
|
||
|
||
|
||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove line breaks from 244 to 248
@hovsepm any other comments? |
@@ -0,0 +1,96 @@ | |||
| |||
namespace Microsoft.Rest.ClientRuntime.Tests.CustomClients | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
License header?
@@ -253,7 +269,7 @@ protected static HttpClientHandler CreateRootHandler() | |||
/// <summary> | |||
/// Gets the HttpClient used for making HTTP requests. | |||
/// </summary> | |||
public HttpClient HttpClient { get; protected set; } | |||
public virtual HttpClient HttpClient { get; protected set; } | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this one - I still consider it as a potential bug hole. We use Get and Set of the HttpClient property during ServiceClient constructor code. So we put all the responsibility on the developers -> they need to be careful and do not use any objects that are not yet initialized in the overwritten property.
- if you walk over the call stack of ServiceClient ctr then HttpClient.Set method is called before any HttpClient.Get method call.
- By overriding just Get you will lose whatever was Set in the base class constructor.
- In your example in FabricamServiceClient class you completely ignore the HttpClient that was passed in the public FabricamServiceClient(HttpClient httpClient) constructor (because all your logic of initialization of HttpClient is happening in the HttpClient Get). Then why do you even expose a constructor that takes httpClient parameter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hovsepm
As mentioned in the description, there are two ways to solve this problem
- Provide constructor overload with HttpClient parameter (more code churn, more paths to cover in tests)
- Make the HttpClient virtual, so classes that inherit from ServiceClient can override their own HttpClient.
#2 The sole purpose of making it virtual is to allow derived classes to override whatever was set by default, in this case a default HttpClient.
#3 The Fabricam test itself is a proof for the scenario where passed in HttpClient can still be overridden.
If we go with the virtual route, we do not necessarily have to provide an overload for the constructor for our clients.
Let's talk more about your concern about potential bug. Could you provide a potential bug that I might have missed. The entire concern on Set is called in constructor is something I would like to understand better.
I think making it HttpClient property virtual is less risky and far less code churn than providing an overload.
If we go with the "making it virtual" route, we do not need any regenerating of code for the clients via autorest for new clients.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shahabhijeet I do not see any real world scenario of the usefulness of having HttpClient as a virtual property on the base abstract ServiceClient class. Please revise/add better example of it's usefulness or remove "virtual". This is a code in the core component and we need to be careful not to introduce potential issues in dependent code.
… constructor. Added tests Fixed failing test for Operational Insights. Cleaned up test code for service client tests Adding missing license headers.
…-net into addHttpClient
Closing this PR and will open a new one. Again getting hit by git issues due to pull merges and unable to rebase to eliminate polluting git log/history. |