7 ms·
I really am trying to understand this better. Can you give me an example with some concrete type names where it's massive waste and in the way? When I think D
by shireboy 6y ago
I really am trying to understand this better. Can you give me an example with some concrete type names where it's massive waste and in the way?
When I think DI, I think:
//Startup.cs has all the config "goo" I don't want to repeat elsewhere.
services.AddDbContext<MyDbContext>(o=>o.UseSqlServer(config.GetConnectionString("foo"));
services.AddTransient<MyService>();
//MyController.cs (or Page, etc) and others get to use it with no ceremony:
public MyController(MyService foo){ this.foo = foo; }
vs no DI, where the config "goo" has to be repeated in every place I intend to use it (or in this case it could also be buried in MyService.cs):
public MyController(){this.foo = new MyService(new MyDbContext(ConfigurationManager.GetConnectionString("foo")));}
public Dispose(){this.foo.Dispose();}
If I knew MyService would never be swapped out and only ever used in one place, I may opt for the no-DI route. I'll often start there then move it to DI when I want testability, reuse of config, plugability, etc..
- DougWebb 6y agoThe way to manage this without DI would be a static method someplace (Startup.cs or elsewhere) which creates the new MyService, stores it, and returns a reference. Then any controllers or pages that need the reference call the static method. The method could return a MyService, or an IMyService if you want to be more flexible. It can always create a fresh object, manage and return a singleton object, or manage a pool of objects. For the new and pool cases, you can have another static method for 'returning' the object when the controller/page is done with it, so you can manage disposal or pool availability. The biggest advantage I see to this approach is in debugging: there is a clear stack trace back to the source of the object, and also to its implementation if you're not using an interface. With DI you often can't tell where an object came from, and sometimes it takes some digging to even find out its exact type (unless you only have one implementation of each interface, which is often the case.)
- ivanche 6y agoThis is well known Service Locator anti-pattern. Described in many places, maybe this one is the most famous https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/ https://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Patt...
- didibus 6y agoNah, ServiceLocator is another overly abstruse pattern. What you do instead is just: public static IMyService myService; public static IMyService getMyService() { if myService return myService; else if(isInTest()) return mockedMyService; else return new MyProdService(wtv); } And call that in your controller that needs to use MyService.
- sharpercoder 6y agoAbove code is the servicelocator pattern. It's just for one service.
- deleted 6y ago[deleted]
- didibus 6y agoServiceLocator has you create a runtime service registry where you can dynamically register and fetch instances too and from. And often that means it bypasses static type checking, as you might be adding and fetching services by name using a string. This is different in that it's static. You don't add a service to it, it creates it the first time you ask for it (if singleton), or everytime you ask for it (otherwise), or pools it, etc. I recon some similarities, but most enterprise "service locator" involve a lot more than this, and often are meant to give you this runtime dynamism where you can load and unload services as the app is running, etc. making them way more complex for apps that don't care about this.
- shireboy 6y agoActually, as written, myService never gets set, but I think I know what you mean. This is not thread-safe and assumes you want singleton. To use it you would in each controller do: var service = Startup.getMyService(); And potentially know if the controller should dispose service. This doesn't seem much less "in the way" or "massive" than: services.AddSingleton<IMyService,MyService>();
- whelming_wave 6y ago