ActivatorUtilities.CreateInstance requires a service provider in order to properly resolve. The service provider is whats being used when resolving injected properties in razor components/pages.
If I want to make use of this in my razor components/pages, do I need to also inject a service provider or a means to get a service provider like through iservicescopefactory? Seems somewhat repetitive but not sure if there's an alternative to this approach.
Background: What I'd like to do is use this utility function to create services that require state values to properly instantiate (values not available when initially constructing the service collection in program.cs) while also leveraging the services already available in my service provider. Not sure if it makes sense to use this to continue making use of di or to just manually construct the class on the fly using the state values
Related
I am implementing a Custom Configuration Provider in my application.
In that provider, I have to make a REST API call. That call needs a valid OAuth 2 Token to succeed. To get that token I need a semi complicated tree of class dependencies.
For the rest of my application, I just use dependency injection to get the needed instance. But a custom configuration provider is called well before dependency injection is setup.
I have thought about making a "Pre" instance of dependency injection. Like this:
IServiceCollection services = new ServiceCollection();
// Setup the DI here
IServiceProvider serviceProvider = services.BuildServiceProvider();
var myTokenGenerator = serviceProvider.GetService<IMyTokenGenerator>();
But I have read that when you make another ServiceCollection, it can cause problems. I would like to know the way to avoid those problems.
How do I correctly cleanup a "pre-DI" instance of ServiceCollection and ServiceProvider?
(Note: Neither one seems to implement IDisposable.)
Hm, I don't get the point why you want to do it that way.
I'd probably get the Serviceprovider fully build.
To avoid that retrieved services affect each other I'd would use nested containers/scopes which means that if you retrieve retrieve the same service you get different instances per container/scope.
Hopefully I understood what you want to achieve.
See
.NET Core IServiceScopeFactory.CreateScope() vs IServiceProvider.CreateScope() extension
In my current Asp.Net application I am finding a number core services that are slowly spreading throughout the application through the use of Dependency Injection. One of those services is the need to know who the current authenticated user is. I have a UserService that encapsulates the logic for getting the CurrentUser, but it seems like I am injecting this same service almost everywhere in my application. Is there a different method I could be using for accessing this Global service without constantly growing my constructors to inject yet another object into my classes? (of course I still want to maintain testability)
I'm creating a new application in Zend Framework 3 and i have a question about a design pattern
Without entering in much details this application will have several Services, as in, will be connecting to external APIs and even in multiple databases, the workflow is also very complex, a single will action can have multiple flows depending on several external information (wich user logged in, configs, etc).
I know about dependency injections and Zend Framework 3 Service Manager, however i am worried about instanciating sereval services when the flow will actually use only a few of them in certain cases, also we will have services depending on other services aswell, for this, i was thinking about using singletons.
Is singleton really a solution here? I was looking a way to user singletons in Zend Framework 3 and haven't figured out a easy way since i can't find a way to user the Service Manager inside a service, as I can't retrive the instance of the Service Manager outside of the Factory system.
What is an easy way to implement singletons in Zend Framework 3?
Why use singletons?
You don't need to worry about too many services in your service manager since they are started only when you get them from the service manager.
Also don't use the service manager inside another class except a factory. In ZF3 it's removed from the controllers for a reason. One of them is testability. If all services are inject with a factory, you can easily write tests. Also if you read your code next year, you can easily see what dependencies are needed inside a class.
If you find there are too many services being injected inside a class which are not always needed you can:
Use the ProxyManager. This lazy loads a service but doesn't start it until a method is called.
Split the service: Move some parts from a service into a new service. e.g. You don't need to place everything in an UserService. You can also have an UserRegisterService, UserEmailService, UserAuthService and UserNotificationsService.
In stead of ZF3, you can also think about zend-expressive. Without getting into too much detail, it is a lightweight middleware framework. You can use middleware to detect what is needed for a request and route to the required action to process the request. Something like this can probably also done in ZF3 but maybe someone else can explain how to do it there.
I have existing code that uses System.Configuration.Provider namespace for provider collections to plugin various implementations of interfaces, where multiple implementations exist in the collection and are selected by name according to various logic.
This namespace is not available in .net core, so I'm looking for advice on how to implement a replacement solution that will work with .net core framework.
I know that if I was just trying to plugin one implementation, I could do it by dependency injection. But I'm looking for a way to have multiple implementations available to choose based on name.
My current implementation with provider model populates the provider collection from a folder where you can drop in xml files that declare the type of the actual implementations, so new implementations of the provider can be loaded from an assembly by just adding another file to the folder. I'd like to keep the logic as similar as possible to that but I'm open to json files rather than xml.
I am thinking I could load up a collection of implementations of the interface from json files in Startup and use dependency injection to provide the collection where needed or perhaps an interface that can get the collection would be lighter weight and allow getting them when they are needed rather than at startup.
Is that the right approach? Anyone have better ideas or done something similar?
This is done more generically than using an abstract base class like ProviderBase in the new framework. You can register multiple of the same service with the DI framework and get them all either simply by asking for an IEnumerable<> of the type you register them as or using the GetRequiredServices<> extension method. Once you get your services, however, you'll need some other way of distinguishing them, such as a property indicating a unique name, which is the pattern the ASP.Net team has been following.
You can see an example in the Identity framework v3 with the Token Providers.
IUserTokenProvider<T>, the "provider"
UserManager, which consumes the token managers
If you have a decent layered ASP.NET MVC 3 web application with a data service class pumping out view models pulled from a repository, sending JSON to an Ajax client,
[taking a breath]
what's a good way to add data filtering based on ASP.NET logins and roles without really messing up our data service class with these concerns?
We have a repository that kicks out Entity Framework 4.1 POCOs which accepts Lambda Expressions for where clauses (or specification objects.)
The data service class creates query objects (like IQueryable) then returns them with .ToList() in the return statement.
I'm thinking maybe a specification that handles security roles passed to the data service class, or somehow essentially injecting a Lambda Expression in just the right place in the data service class?
I am sure there is a fairly standardized pattern to implement something like this. Links to examples or books on the subject would be most appreciated.
If you've got a single-tiered application (as in, your web layer and service/data layer all run in the same process) then it's common to use a custom principal to achieve what you want.
You can use a custom principal to store extra data about a user (have a watch of this: http://www.asp.net/security/videos/use-custom-principal-objects), but the trick is to set this custom principal into the current thread's principal also, by doing Thread.CurrentPrincipal = myPrincipal
This effectively means that you can get access to your user/role information from deep into your service layer without creating extra parameters on your methods (which is bad design). You can do this by querying Thread.CurrentPrincipal and cast it to your own implementation.
If your service/data layer exists in a different process (perhaps you're using web services) then you can still pass your user information separately from your method calls, by passing custom data headers along with the service request and leave this kind of data out of your method calls.
Edit: to relate back to your querying of data, obviously any queries you write which are influence by some aspect of the currently logged-in user or their role can be picked up by looking at the data in your custom principal, but without passing special data through your method calls.
Hopefully this at least points you in the right direction.
It is not clear from your question if you are using DI, as you mentioned you have your layers split up properly I am presuming so, then again this should be possible without DI I think...
Create an interface called IUserSession or something similar, Implement that inside your asp.net mvc application, the interface can contain something like GetUser(); from this info I am sure you can filter data inside your middle tier, otherwise you can simply use this IUserSession inside your web application and do the filtering inside that tier...
See: https://gist.github.com/1042173