AspNetCore - Injecting a Func [closed]Is this SqlConnection / SqlCommand async wrapper both efficient and...

What do you call something that goes against the spirit of the law, but is legal when interpreting the law to the letter?

How long does it take to type this?

Are there any consumables that function as addictive (psychedelic) drugs?

A Journey Through Space and Time

Accidentally leaked the solution to an assignment, what to do now? (I'm the prof)

DOS, create pipe for stdin/stdout of command.com(or 4dos.com) in C or Batch?

declaring a variable twice in IIFE

Infinite past with a beginning?

TGV timetables / schedules?

What Brexit solution does the DUP want?

What defenses are there against being summoned by the Gate spell?

How to make payment on the internet without leaving a money trail?

Why CLRS example on residual networks does not follows its formula?

N.B. ligature in Latex

Are tax years 2016 & 2017 back taxes deductible for tax year 2018?

What would happen to a modern skyscraper if it rains micro blackholes?

How can the DM most effectively choose 1 out of an odd number of players to be targeted by an attack or effect?

How do you conduct xenoanthropology after first contact?

Why has Russell's definition of numbers using equivalence classes been finally abandoned? ( If it has actually been abandoned).

Why are 150k or 200k jobs considered good when there are 300k+ births a month?

If Manufacturer spice model and Datasheet give different values which should I use?

Email Account under attack (really) - anything I can do?

Can I interfere when another PC is about to be attacked?

Is it possible to do 50 km distance without any previous training?



AspNetCore - Injecting a Func [closed]


Is this SqlConnection / SqlCommand async wrapper both efficient and correct?Async access to SchoolUpdating WPF MainWindow from an async taskCancellable UI loaderDownloading blobs asynchronouslyWPF async ObservableTaskQueue classSend image between appsDependency injection using function references in C#Injecting the Repository into the business layerSemaphoreSlim limit tasks






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







-2












$begingroup$


I have an ASP.NET Core controller I am creating. The controller endpoint looks something like this right now:



[HttpPost("")]
public async Task<ActionResult<Thing>> AddThing([FromBody] string otherThingId)
{
// First I perform some validation here (null check, proper ID, etc).

// Next I get OtherThing to make a Thing out of it
// _getOtherThing is at the heart of what I'm trying to understand
var sample = await _getOtherThing(otherThingId);

// Finally I do some work to convert it to a Thing and send it back
return newThing;
}


_getOtherThing is a method that performs a very specific concrete call to another API to get the data I needed. It's a method that takes a string and returns a Task<OtherThing>. There are issues with this method as it is though, such as testing, sharing it in the code base, and swapping implementations later on.



To me, it seems like it's an external dependency. So it would make sense to pass it into the controller. The controller class does with the Repository it uses via DI like so:



public ThingController(IThingRepository thingRepo)
{
_thingRepo = thingRepo;
}


The interface and its concrete implementation are then supplied for injection in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
}


So I end up with two questions:




  1. What is the most common/expected way to extract this function and then supply it to the controller?

  2. If I did want to just supply a function, what is the most reasonable way to do it?


With respect to the first question - Here are two strategies I could think of. Are there others?





  1. Supply the function directly to the class. What I came up with looks like this:


public ThingController(IThingRepository thingRepo, Func<string, Task<OtherThing>> getOtherThing)
{
_thingRepo = thingRepo;
_getOtherThing = getOtherThing;
}


And then during Startup.cs:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<Func<string, Task<OtherThing>>>(
OtherThingUtils.GetOtherThing
);
}




  1. Convert the function into an interface/class pair and inject that:


interface IOtherThingProvider {
Task<OtherThing> getOtherThing(string id);
}
class OtherThingProvider : IOtherThingProvider {
public async Task<OtherThing> getOtherThing(string id)
{
// original code here
}
}


And then in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<IOtherThingProvider, OtherThingProvider>();
}









share|improve this question









New contributor




pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$



closed as off-topic by 200_success, Gerrit0, t3chb0t, Toby Speight, Edward Apr 2 at 11:37


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – 200_success, Gerrit0, t3chb0t, Toby Speight, Edward

If this question can be reworded to fit the rules in the help center, please edit the question.
















  • $begingroup$
    Also if this is the wrong context to post this in, or if the post is missing something for Cod Review, let me know and I'll correct.
    $endgroup$
    – pseudoramble
    Apr 1 at 18:56










  • $begingroup$
    (This looks solution looking for a problem - can you sketch a use case?)
    $endgroup$
    – greybeard
    Apr 1 at 20:33










  • $begingroup$
    Thanks. My main question was around typical practices in C#. Is it unusual to pass a function directly to a class like this? I will try and clarify!
    $endgroup$
    – pseudoramble
    Apr 2 at 12:33










  • $begingroup$
    I took some time to edit the question to hopefully be more fitting. I left the solutions could think of because they are at least one aspect of my question. Hopefully this helps. Thanks again for the feedback @greybeard
    $endgroup$
    – pseudoramble
    Apr 2 at 13:10










  • $begingroup$
    Also I see I misunderstood what the point of this StackExchange is. Is there a better one to post my question? It might fit fine on StackOverflow now.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:26


















-2












$begingroup$


I have an ASP.NET Core controller I am creating. The controller endpoint looks something like this right now:



[HttpPost("")]
public async Task<ActionResult<Thing>> AddThing([FromBody] string otherThingId)
{
// First I perform some validation here (null check, proper ID, etc).

// Next I get OtherThing to make a Thing out of it
// _getOtherThing is at the heart of what I'm trying to understand
var sample = await _getOtherThing(otherThingId);

// Finally I do some work to convert it to a Thing and send it back
return newThing;
}


_getOtherThing is a method that performs a very specific concrete call to another API to get the data I needed. It's a method that takes a string and returns a Task<OtherThing>. There are issues with this method as it is though, such as testing, sharing it in the code base, and swapping implementations later on.



To me, it seems like it's an external dependency. So it would make sense to pass it into the controller. The controller class does with the Repository it uses via DI like so:



public ThingController(IThingRepository thingRepo)
{
_thingRepo = thingRepo;
}


The interface and its concrete implementation are then supplied for injection in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
}


So I end up with two questions:




  1. What is the most common/expected way to extract this function and then supply it to the controller?

  2. If I did want to just supply a function, what is the most reasonable way to do it?


With respect to the first question - Here are two strategies I could think of. Are there others?





  1. Supply the function directly to the class. What I came up with looks like this:


public ThingController(IThingRepository thingRepo, Func<string, Task<OtherThing>> getOtherThing)
{
_thingRepo = thingRepo;
_getOtherThing = getOtherThing;
}


And then during Startup.cs:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<Func<string, Task<OtherThing>>>(
OtherThingUtils.GetOtherThing
);
}




  1. Convert the function into an interface/class pair and inject that:


interface IOtherThingProvider {
Task<OtherThing> getOtherThing(string id);
}
class OtherThingProvider : IOtherThingProvider {
public async Task<OtherThing> getOtherThing(string id)
{
// original code here
}
}


And then in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<IOtherThingProvider, OtherThingProvider>();
}









share|improve this question









New contributor




pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$



closed as off-topic by 200_success, Gerrit0, t3chb0t, Toby Speight, Edward Apr 2 at 11:37


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – 200_success, Gerrit0, t3chb0t, Toby Speight, Edward

If this question can be reworded to fit the rules in the help center, please edit the question.
















  • $begingroup$
    Also if this is the wrong context to post this in, or if the post is missing something for Cod Review, let me know and I'll correct.
    $endgroup$
    – pseudoramble
    Apr 1 at 18:56










  • $begingroup$
    (This looks solution looking for a problem - can you sketch a use case?)
    $endgroup$
    – greybeard
    Apr 1 at 20:33










  • $begingroup$
    Thanks. My main question was around typical practices in C#. Is it unusual to pass a function directly to a class like this? I will try and clarify!
    $endgroup$
    – pseudoramble
    Apr 2 at 12:33










  • $begingroup$
    I took some time to edit the question to hopefully be more fitting. I left the solutions could think of because they are at least one aspect of my question. Hopefully this helps. Thanks again for the feedback @greybeard
    $endgroup$
    – pseudoramble
    Apr 2 at 13:10










  • $begingroup$
    Also I see I misunderstood what the point of this StackExchange is. Is there a better one to post my question? It might fit fine on StackOverflow now.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:26














-2












-2








-2





$begingroup$


I have an ASP.NET Core controller I am creating. The controller endpoint looks something like this right now:



[HttpPost("")]
public async Task<ActionResult<Thing>> AddThing([FromBody] string otherThingId)
{
// First I perform some validation here (null check, proper ID, etc).

// Next I get OtherThing to make a Thing out of it
// _getOtherThing is at the heart of what I'm trying to understand
var sample = await _getOtherThing(otherThingId);

// Finally I do some work to convert it to a Thing and send it back
return newThing;
}


_getOtherThing is a method that performs a very specific concrete call to another API to get the data I needed. It's a method that takes a string and returns a Task<OtherThing>. There are issues with this method as it is though, such as testing, sharing it in the code base, and swapping implementations later on.



To me, it seems like it's an external dependency. So it would make sense to pass it into the controller. The controller class does with the Repository it uses via DI like so:



public ThingController(IThingRepository thingRepo)
{
_thingRepo = thingRepo;
}


The interface and its concrete implementation are then supplied for injection in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
}


So I end up with two questions:




  1. What is the most common/expected way to extract this function and then supply it to the controller?

  2. If I did want to just supply a function, what is the most reasonable way to do it?


With respect to the first question - Here are two strategies I could think of. Are there others?





  1. Supply the function directly to the class. What I came up with looks like this:


public ThingController(IThingRepository thingRepo, Func<string, Task<OtherThing>> getOtherThing)
{
_thingRepo = thingRepo;
_getOtherThing = getOtherThing;
}


And then during Startup.cs:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<Func<string, Task<OtherThing>>>(
OtherThingUtils.GetOtherThing
);
}




  1. Convert the function into an interface/class pair and inject that:


interface IOtherThingProvider {
Task<OtherThing> getOtherThing(string id);
}
class OtherThingProvider : IOtherThingProvider {
public async Task<OtherThing> getOtherThing(string id)
{
// original code here
}
}


And then in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<IOtherThingProvider, OtherThingProvider>();
}









share|improve this question









New contributor




pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




I have an ASP.NET Core controller I am creating. The controller endpoint looks something like this right now:



[HttpPost("")]
public async Task<ActionResult<Thing>> AddThing([FromBody] string otherThingId)
{
// First I perform some validation here (null check, proper ID, etc).

// Next I get OtherThing to make a Thing out of it
// _getOtherThing is at the heart of what I'm trying to understand
var sample = await _getOtherThing(otherThingId);

// Finally I do some work to convert it to a Thing and send it back
return newThing;
}


_getOtherThing is a method that performs a very specific concrete call to another API to get the data I needed. It's a method that takes a string and returns a Task<OtherThing>. There are issues with this method as it is though, such as testing, sharing it in the code base, and swapping implementations later on.



To me, it seems like it's an external dependency. So it would make sense to pass it into the controller. The controller class does with the Repository it uses via DI like so:



public ThingController(IThingRepository thingRepo)
{
_thingRepo = thingRepo;
}


The interface and its concrete implementation are then supplied for injection in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
}


So I end up with two questions:




  1. What is the most common/expected way to extract this function and then supply it to the controller?

  2. If I did want to just supply a function, what is the most reasonable way to do it?


With respect to the first question - Here are two strategies I could think of. Are there others?





  1. Supply the function directly to the class. What I came up with looks like this:


public ThingController(IThingRepository thingRepo, Func<string, Task<OtherThing>> getOtherThing)
{
_thingRepo = thingRepo;
_getOtherThing = getOtherThing;
}


And then during Startup.cs:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<Func<string, Task<OtherThing>>>(
OtherThingUtils.GetOtherThing
);
}




  1. Convert the function into an interface/class pair and inject that:


interface IOtherThingProvider {
Task<OtherThing> getOtherThing(string id);
}
class OtherThingProvider : IOtherThingProvider {
public async Task<OtherThing> getOtherThing(string id)
{
// original code here
}
}


And then in the Startup.cs file:



public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IThingRepository, ThingRepository>();
services.AddSingleton<IOtherThingProvider, OtherThingProvider>();
}






c# asp.net-core .net-core






share|improve this question









New contributor




pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited Apr 2 at 13:09







pseudoramble













New contributor




pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked Apr 1 at 17:34









pseudoramblepseudoramble

994




994




New contributor




pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






pseudoramble is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




closed as off-topic by 200_success, Gerrit0, t3chb0t, Toby Speight, Edward Apr 2 at 11:37


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – 200_success, Gerrit0, t3chb0t, Toby Speight, Edward

If this question can be reworded to fit the rules in the help center, please edit the question.







closed as off-topic by 200_success, Gerrit0, t3chb0t, Toby Speight, Edward Apr 2 at 11:37


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – 200_success, Gerrit0, t3chb0t, Toby Speight, Edward

If this question can be reworded to fit the rules in the help center, please edit the question.












  • $begingroup$
    Also if this is the wrong context to post this in, or if the post is missing something for Cod Review, let me know and I'll correct.
    $endgroup$
    – pseudoramble
    Apr 1 at 18:56










  • $begingroup$
    (This looks solution looking for a problem - can you sketch a use case?)
    $endgroup$
    – greybeard
    Apr 1 at 20:33










  • $begingroup$
    Thanks. My main question was around typical practices in C#. Is it unusual to pass a function directly to a class like this? I will try and clarify!
    $endgroup$
    – pseudoramble
    Apr 2 at 12:33










  • $begingroup$
    I took some time to edit the question to hopefully be more fitting. I left the solutions could think of because they are at least one aspect of my question. Hopefully this helps. Thanks again for the feedback @greybeard
    $endgroup$
    – pseudoramble
    Apr 2 at 13:10










  • $begingroup$
    Also I see I misunderstood what the point of this StackExchange is. Is there a better one to post my question? It might fit fine on StackOverflow now.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:26


















  • $begingroup$
    Also if this is the wrong context to post this in, or if the post is missing something for Cod Review, let me know and I'll correct.
    $endgroup$
    – pseudoramble
    Apr 1 at 18:56










  • $begingroup$
    (This looks solution looking for a problem - can you sketch a use case?)
    $endgroup$
    – greybeard
    Apr 1 at 20:33










  • $begingroup$
    Thanks. My main question was around typical practices in C#. Is it unusual to pass a function directly to a class like this? I will try and clarify!
    $endgroup$
    – pseudoramble
    Apr 2 at 12:33










  • $begingroup$
    I took some time to edit the question to hopefully be more fitting. I left the solutions could think of because they are at least one aspect of my question. Hopefully this helps. Thanks again for the feedback @greybeard
    $endgroup$
    – pseudoramble
    Apr 2 at 13:10










  • $begingroup$
    Also I see I misunderstood what the point of this StackExchange is. Is there a better one to post my question? It might fit fine on StackOverflow now.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:26
















$begingroup$
Also if this is the wrong context to post this in, or if the post is missing something for Cod Review, let me know and I'll correct.
$endgroup$
– pseudoramble
Apr 1 at 18:56




$begingroup$
Also if this is the wrong context to post this in, or if the post is missing something for Cod Review, let me know and I'll correct.
$endgroup$
– pseudoramble
Apr 1 at 18:56












$begingroup$
(This looks solution looking for a problem - can you sketch a use case?)
$endgroup$
– greybeard
Apr 1 at 20:33




$begingroup$
(This looks solution looking for a problem - can you sketch a use case?)
$endgroup$
– greybeard
Apr 1 at 20:33












$begingroup$
Thanks. My main question was around typical practices in C#. Is it unusual to pass a function directly to a class like this? I will try and clarify!
$endgroup$
– pseudoramble
Apr 2 at 12:33




$begingroup$
Thanks. My main question was around typical practices in C#. Is it unusual to pass a function directly to a class like this? I will try and clarify!
$endgroup$
– pseudoramble
Apr 2 at 12:33












$begingroup$
I took some time to edit the question to hopefully be more fitting. I left the solutions could think of because they are at least one aspect of my question. Hopefully this helps. Thanks again for the feedback @greybeard
$endgroup$
– pseudoramble
Apr 2 at 13:10




$begingroup$
I took some time to edit the question to hopefully be more fitting. I left the solutions could think of because they are at least one aspect of my question. Hopefully this helps. Thanks again for the feedback @greybeard
$endgroup$
– pseudoramble
Apr 2 at 13:10












$begingroup$
Also I see I misunderstood what the point of this StackExchange is. Is there a better one to post my question? It might fit fine on StackOverflow now.
$endgroup$
– pseudoramble
Apr 2 at 13:26




$begingroup$
Also I see I misunderstood what the point of this StackExchange is. Is there a better one to post my question? It might fit fine on StackOverflow now.
$endgroup$
– pseudoramble
Apr 2 at 13:26










1 Answer
1






active

oldest

votes


















2












$begingroup$

You basically butcher the entire reason to dependency inject here.
Some IoCs let you deffer injection by doing public MyConstructor(Func<IMyInterface> factory). This is fine, because IMyInterface is an interface and the concrete implementation will be invoked through the standard pipeline and it can have its own dependencies.



But your solution cuts off the DI pipeline half way through and the OverThingUtils.GetOtherThing can not benefit from DI at all. And the special Func<string, IType> construct is dangerously close to service locator pattern.



I would create an interface,



interface IOtherThingProvider 
{
Task<OtherThing> GetOtherThing(string id);
}





share|improve this answer









$endgroup$













  • $begingroup$
    So what you're saying is instead of using a function and defining the type in the constructor, I should build an interface/class and use that in the constructor? At that point the DI framework will do the work of creating an instance of the class when needed. Is that right?
    $endgroup$
    – pseudoramble
    Apr 2 at 12:30










  • $begingroup$
    Exactly,and the concrete type can benefit from DI and have its own dependencies. Etc, etc
    $endgroup$
    – Anders
    Apr 2 at 13:01










  • $begingroup$
    Cool, thanks for answering! I also rewrote the question to hopefully be better than it was originally.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:11










  • $begingroup$
    Just be careful with singleton scope. Anything injected into its constructor will be singleton.
    $endgroup$
    – Anders
    Apr 2 at 13:15










  • $begingroup$
    You can Create a scope but for that you need to i have dependency to IServiceCollection and then you are again danger close to service locator pattern. Its fine for a few framework specific things. But you should be careful spreading depedency to the iOC. If need alot of scoped life times deep down in your domain. Its better to abstract the scope. I did this for one of my projects. andersmalmgren.com/2015/06/23/abstract-di-container-scopes
    $endgroup$
    – Anders
    Apr 2 at 13:18


















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2












$begingroup$

You basically butcher the entire reason to dependency inject here.
Some IoCs let you deffer injection by doing public MyConstructor(Func<IMyInterface> factory). This is fine, because IMyInterface is an interface and the concrete implementation will be invoked through the standard pipeline and it can have its own dependencies.



But your solution cuts off the DI pipeline half way through and the OverThingUtils.GetOtherThing can not benefit from DI at all. And the special Func<string, IType> construct is dangerously close to service locator pattern.



I would create an interface,



interface IOtherThingProvider 
{
Task<OtherThing> GetOtherThing(string id);
}





share|improve this answer









$endgroup$













  • $begingroup$
    So what you're saying is instead of using a function and defining the type in the constructor, I should build an interface/class and use that in the constructor? At that point the DI framework will do the work of creating an instance of the class when needed. Is that right?
    $endgroup$
    – pseudoramble
    Apr 2 at 12:30










  • $begingroup$
    Exactly,and the concrete type can benefit from DI and have its own dependencies. Etc, etc
    $endgroup$
    – Anders
    Apr 2 at 13:01










  • $begingroup$
    Cool, thanks for answering! I also rewrote the question to hopefully be better than it was originally.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:11










  • $begingroup$
    Just be careful with singleton scope. Anything injected into its constructor will be singleton.
    $endgroup$
    – Anders
    Apr 2 at 13:15










  • $begingroup$
    You can Create a scope but for that you need to i have dependency to IServiceCollection and then you are again danger close to service locator pattern. Its fine for a few framework specific things. But you should be careful spreading depedency to the iOC. If need alot of scoped life times deep down in your domain. Its better to abstract the scope. I did this for one of my projects. andersmalmgren.com/2015/06/23/abstract-di-container-scopes
    $endgroup$
    – Anders
    Apr 2 at 13:18
















2












$begingroup$

You basically butcher the entire reason to dependency inject here.
Some IoCs let you deffer injection by doing public MyConstructor(Func<IMyInterface> factory). This is fine, because IMyInterface is an interface and the concrete implementation will be invoked through the standard pipeline and it can have its own dependencies.



But your solution cuts off the DI pipeline half way through and the OverThingUtils.GetOtherThing can not benefit from DI at all. And the special Func<string, IType> construct is dangerously close to service locator pattern.



I would create an interface,



interface IOtherThingProvider 
{
Task<OtherThing> GetOtherThing(string id);
}





share|improve this answer









$endgroup$













  • $begingroup$
    So what you're saying is instead of using a function and defining the type in the constructor, I should build an interface/class and use that in the constructor? At that point the DI framework will do the work of creating an instance of the class when needed. Is that right?
    $endgroup$
    – pseudoramble
    Apr 2 at 12:30










  • $begingroup$
    Exactly,and the concrete type can benefit from DI and have its own dependencies. Etc, etc
    $endgroup$
    – Anders
    Apr 2 at 13:01










  • $begingroup$
    Cool, thanks for answering! I also rewrote the question to hopefully be better than it was originally.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:11










  • $begingroup$
    Just be careful with singleton scope. Anything injected into its constructor will be singleton.
    $endgroup$
    – Anders
    Apr 2 at 13:15










  • $begingroup$
    You can Create a scope but for that you need to i have dependency to IServiceCollection and then you are again danger close to service locator pattern. Its fine for a few framework specific things. But you should be careful spreading depedency to the iOC. If need alot of scoped life times deep down in your domain. Its better to abstract the scope. I did this for one of my projects. andersmalmgren.com/2015/06/23/abstract-di-container-scopes
    $endgroup$
    – Anders
    Apr 2 at 13:18














2












2








2





$begingroup$

You basically butcher the entire reason to dependency inject here.
Some IoCs let you deffer injection by doing public MyConstructor(Func<IMyInterface> factory). This is fine, because IMyInterface is an interface and the concrete implementation will be invoked through the standard pipeline and it can have its own dependencies.



But your solution cuts off the DI pipeline half way through and the OverThingUtils.GetOtherThing can not benefit from DI at all. And the special Func<string, IType> construct is dangerously close to service locator pattern.



I would create an interface,



interface IOtherThingProvider 
{
Task<OtherThing> GetOtherThing(string id);
}





share|improve this answer









$endgroup$



You basically butcher the entire reason to dependency inject here.
Some IoCs let you deffer injection by doing public MyConstructor(Func<IMyInterface> factory). This is fine, because IMyInterface is an interface and the concrete implementation will be invoked through the standard pipeline and it can have its own dependencies.



But your solution cuts off the DI pipeline half way through and the OverThingUtils.GetOtherThing can not benefit from DI at all. And the special Func<string, IType> construct is dangerously close to service locator pattern.



I would create an interface,



interface IOtherThingProvider 
{
Task<OtherThing> GetOtherThing(string id);
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Apr 2 at 11:33









AndersAnders

22416




22416












  • $begingroup$
    So what you're saying is instead of using a function and defining the type in the constructor, I should build an interface/class and use that in the constructor? At that point the DI framework will do the work of creating an instance of the class when needed. Is that right?
    $endgroup$
    – pseudoramble
    Apr 2 at 12:30










  • $begingroup$
    Exactly,and the concrete type can benefit from DI and have its own dependencies. Etc, etc
    $endgroup$
    – Anders
    Apr 2 at 13:01










  • $begingroup$
    Cool, thanks for answering! I also rewrote the question to hopefully be better than it was originally.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:11










  • $begingroup$
    Just be careful with singleton scope. Anything injected into its constructor will be singleton.
    $endgroup$
    – Anders
    Apr 2 at 13:15










  • $begingroup$
    You can Create a scope but for that you need to i have dependency to IServiceCollection and then you are again danger close to service locator pattern. Its fine for a few framework specific things. But you should be careful spreading depedency to the iOC. If need alot of scoped life times deep down in your domain. Its better to abstract the scope. I did this for one of my projects. andersmalmgren.com/2015/06/23/abstract-di-container-scopes
    $endgroup$
    – Anders
    Apr 2 at 13:18


















  • $begingroup$
    So what you're saying is instead of using a function and defining the type in the constructor, I should build an interface/class and use that in the constructor? At that point the DI framework will do the work of creating an instance of the class when needed. Is that right?
    $endgroup$
    – pseudoramble
    Apr 2 at 12:30










  • $begingroup$
    Exactly,and the concrete type can benefit from DI and have its own dependencies. Etc, etc
    $endgroup$
    – Anders
    Apr 2 at 13:01










  • $begingroup$
    Cool, thanks for answering! I also rewrote the question to hopefully be better than it was originally.
    $endgroup$
    – pseudoramble
    Apr 2 at 13:11










  • $begingroup$
    Just be careful with singleton scope. Anything injected into its constructor will be singleton.
    $endgroup$
    – Anders
    Apr 2 at 13:15










  • $begingroup$
    You can Create a scope but for that you need to i have dependency to IServiceCollection and then you are again danger close to service locator pattern. Its fine for a few framework specific things. But you should be careful spreading depedency to the iOC. If need alot of scoped life times deep down in your domain. Its better to abstract the scope. I did this for one of my projects. andersmalmgren.com/2015/06/23/abstract-di-container-scopes
    $endgroup$
    – Anders
    Apr 2 at 13:18
















$begingroup$
So what you're saying is instead of using a function and defining the type in the constructor, I should build an interface/class and use that in the constructor? At that point the DI framework will do the work of creating an instance of the class when needed. Is that right?
$endgroup$
– pseudoramble
Apr 2 at 12:30




$begingroup$
So what you're saying is instead of using a function and defining the type in the constructor, I should build an interface/class and use that in the constructor? At that point the DI framework will do the work of creating an instance of the class when needed. Is that right?
$endgroup$
– pseudoramble
Apr 2 at 12:30












$begingroup$
Exactly,and the concrete type can benefit from DI and have its own dependencies. Etc, etc
$endgroup$
– Anders
Apr 2 at 13:01




$begingroup$
Exactly,and the concrete type can benefit from DI and have its own dependencies. Etc, etc
$endgroup$
– Anders
Apr 2 at 13:01












$begingroup$
Cool, thanks for answering! I also rewrote the question to hopefully be better than it was originally.
$endgroup$
– pseudoramble
Apr 2 at 13:11




$begingroup$
Cool, thanks for answering! I also rewrote the question to hopefully be better than it was originally.
$endgroup$
– pseudoramble
Apr 2 at 13:11












$begingroup$
Just be careful with singleton scope. Anything injected into its constructor will be singleton.
$endgroup$
– Anders
Apr 2 at 13:15




$begingroup$
Just be careful with singleton scope. Anything injected into its constructor will be singleton.
$endgroup$
– Anders
Apr 2 at 13:15












$begingroup$
You can Create a scope but for that you need to i have dependency to IServiceCollection and then you are again danger close to service locator pattern. Its fine for a few framework specific things. But you should be careful spreading depedency to the iOC. If need alot of scoped life times deep down in your domain. Its better to abstract the scope. I did this for one of my projects. andersmalmgren.com/2015/06/23/abstract-di-container-scopes
$endgroup$
– Anders
Apr 2 at 13:18




$begingroup$
You can Create a scope but for that you need to i have dependency to IServiceCollection and then you are again danger close to service locator pattern. Its fine for a few framework specific things. But you should be careful spreading depedency to the iOC. If need alot of scoped life times deep down in your domain. Its better to abstract the scope. I did this for one of my projects. andersmalmgren.com/2015/06/23/abstract-di-container-scopes
$endgroup$
– Anders
Apr 2 at 13:18



Popular posts from this blog

is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...