Is it possible to get an instance of a service without having a WorkItem context?
I have a some classes that need to access some services, and i'm wondering if it's possible to get those services without explicitly injecting those services in the class.
As all the services are registered in WorkItem or rootWorkItem context its not possible according to the design rules of CAB/SCSF.
Please elaborate why you cannot register the service in WorkItem and get it from there. CAB/SCSF has proposed the best practices to manage an enterprise application, its upto us how much we benefit from it.
But if its really necessary you can have a static class (which can act as service implemented in singleton way) in Infrastructure.Library and refer this assembly in your Business or Functional module to get it.
Its a bad hack but technically doable.
Related
My layout
project.web (.net core 2.1 web api)
Some binding models (for post/put requests) and resource models for GET requests
Controllers.
I only call interfaces from (x.api) which are resolved to x.core services.
No validation or anything. This happens inside the core layer
I've setup a few things like automapper and swagger, that are not relevant for my question.
project.api (class lib)
only contains interfaces for .core and .store projects (services, repositories and domain models)
project.core (class lib)
two kinds of services
1) Services which call the repository services (interfaces). But validate the data before calling the repo service.
2) Services that will have to execute long term stuff (IE: scanning folders, handling file information, ...). I actually created HostedServices for these as a folder could easily contain thousands of files.
project.store (class lib)
Wrapper services for my storage (Only contains helper methods so I don't have to write the same queries a hundred times.)
Problem / question
At this time I have registered all of my services and repositories as singletons in public void ConfigureServices(IServiceCollection services)
because I was using a different storage (nosql, litedb) before refactoring code to EF (sqllite)
Now the problem is that I want to register my DbContext as scoped (by default)
But my repositories (singleton) depend on dbcontext. Which means I will have to make these scoped as well. I'm ok with this, as these are only wrapper services, so I don't have to write the same queries all the time.
But some other services, that will need access to my data are singletons, and I cannot register these as scoped. Contains some data that needs to be the same for every request, and some collections and long running jobs.
I can think of two solutions
The first solution is to make a dependency to IServiceScopeFactory in my repository and use something like using (var scope = ServiceScopeFactory.CreateScope()) { scope.ServiceProvider.GetService(typeof(MyDbContext))... }
this way I can remove the dependency from my repository wrapper, but this doesn't sound clean to me.
The other solution is to register all of my services that only handle database stuff as scoped. (IE customerSservice in core only does validations and calls customerRepository) I remove dependencies from my remaining singleton services.
In those singletons, instead of depending on the customersService, I could use a rest call with restsharp or something similar
Just like how I would consume them from my windows client applications and web client apps.
I don't actually like either. But perheps someone can give me some advice or thoughts?
Well, the two options you laid out are in fact your only two options. The first is the service locator antipattern, which as the name implies, is something you should avoid. However, when you are dealing with singleton-scoped objects needing access to objects in other scopes, there is no other way.
The only other option is to reduce the scope of your services from singletons, such that you can then inject the context directly. Not everything necessarily needs to be a singleton. Generally, if you need to utilize something like DbContext, there's a strong argument to be made that your object should not be singleton-scope in the first place. If you need it to be singleton-scoped, that's most likely an indication that the class is either doing too much or is otherwise brittle.
I would like to know in best practice questions and think of easily testable classes, when I need multiple different instances of the same (fabricated) object within a specific class, which approach is recommended?
Before I used the Service Manager build method, but it is no longer recommended to inject Service Manager directly into a class, right?
I am currently developing a Xamarin Forms app and am in the process of reworking it to work with Prism. I'm really trying to adhere to MVVM design patterns (I'm trying to grow as an amateur developer and learn how to use them).
1) Is it improper from a MVVM design pattern perspective to utilize messaging services (Prism's EventAggregator) and UI interactions (Prism's PageDialogService) outside of VMs? I've written several "services" that are called from the VM and have found a need to access both messaging and UI services. As one example, The VM calls a service, the service retrieves and processes some data, ask a question to the user based upon those calculations and then continue to finish processing returning the desired value. To be proper, should control be returned back to the VM to "just" ask the question?
2) If it's not verboten, is it possible to access the services outside of VMs? It does not readily appear to me that I can inject them into the constructor of the service. Is it okay to "pass" them into the service's function I'm calling along with other parameters? That just seems un... MVVM-ish?
Update:
I'm not sure all my steps were necessary, but with the help below I got it working. First I converted my singleton service into an interface (IMyService) and an implementing class (MyService). Next, I overrode ConfigureContainer in App.xaml.cs and called Container.RegisterType<IMyService, MyService>(new ContainerControlledLifetimeManager());
I could then inject IMyService, just like IEventAggregator and IPageDialogService into my ViewModels and I could also inject those services into the public constructor of my implementing class (MyService).
ad 1) the event aggregator is meant primarily for UI, but you can use it as message bus in other parts of the app, too, if you don't need the more advanced features of a "real" message bus.
ad 2) unity will happily inject dependencies into services that are themselves dependencies of view models or other services. That's what a dependency injection container does :-)
I am bit confused about services in DDD.
First of all. Why are services always expressed as an Interface? Is that a rule?
Why do services contain only one method? Sometimes it makes sense to implement related methods in a single class.
Do I have to make services for each repository? I must be doing something wrong because I find myself making services for CRUD operations.
For example I have a repository with the usual methods. How do I control the access to the objects persisted in the repository? I tend to make services with lots of reading methods. Those services can check the user roles and then decide if the user can use the objects or not. I feel something is not good in my design.
I'm assuming you're talking about domain services. There are other types of services in DDD such as application services and infrastructure services.
First of all. Why are services always expressed as an Interface? Is
that a rule?
No this is not a rule. Only create an interface abstraction when there is a need for it.
Why do services contain only one method? Sometimes it makes sense to
implement related methods in a single class.
A service with a single method can be thought of as implementing a single operation - a single use case. If it makes sense to encapsulate multiple operations in a single object than this is also acceptable. However, conflating multiple responsibilities into a single class often leads to violation of SRP.
Do I have to make services for each repository?
No. A repository is already a sort of service. More specifically, a repository implementation can be thought of as an infrastructure service.
It is the application service which calls a repository in order to implement some use case. It delegates to domain entities and orchestrates other services that may be required for a given operation. Take a look at Services in DDD for an example of the various services interacting.
I just successfully implemented a WF4 "versioning" system using WCF's Routing Service. I had a version1 workflow service to which I added a new Decision activity and saved it as a version2 service. So now I have 2 endpoints (with identical service contracts, i.e. all Receive activities are the same for both service) and a router that checks the content of a message (a "versionId" string on the object that all of my Receive's accept as an argument) to decide which endpoint to hit.
My question is, while this works fine when no changes are made to the service contract, how to I handle the need to add or remove methods from my service contract and create a version3 service? My original thought was, when I add the service reference to my client, I use the latest workflow service's endpoint to get the latest service contract. Then, in the config file, I change the endpoint I connect to to the router's endpoint. But this won't work if v1 and v2 have a different contract than v3. My proxy will have v3's methods and forget all about v1 and v2.
Any ideas of how to handle this? Should I create an actual service contract interface in my workflow solution (instead of just supplying a ServiceContractName in my Receive activities)?
If the WCF contract changes your client will need to be aware of the additional operations and when to call them. I have used the active bookmarks, it contains the WCF operation, from the persistence store in some applications to have the client app adapt to the workflow dynamically by checking the enabled bookmarks and enabling/disabling UI controls based on that. The client will still have to be updated when new operations are added to a new version of the workflow.
While WCF was young I heard a few voices arguing that endpoint versioning (for web services that is) should be accomplished by using a folder structure. I never got to the point of trying it out myself, but just analyzing the consequences of such a strategy seems to me as a splendid solution. I have no production experience of WCF, but am about to launch a rather comprehensive solution using version 4.0 of .NET (ASP.NET, WCF, WF...) and at this stage I would argue that using a folder structure to separate versions of endpoints would be a good solution.
The essence of such a strategy would be to never change or remove the contract of an endpoint (a specific version) until you are 100% sure that it is not used any more. While your services evolves you would just add new contracts and endpoints. This could lead to code duplication if one is not such a structured developer as one should be. But by introducing a service facade the duplication would be insignificant
I have been through the same situation. You can maintain the version by the help of custom implementation. save the Workflow Service URL in Database. And invoke them as per desire.
You can get the information about calling the WF Service with the URL by the client.
http://rajeevkumarsrivastava.blogspot.in/2014/08/consume-workflow-service-45-from-client.html
Hope this helps