Registry equivalent in Unity - unity-container

Is there any equivalent to the Registry class from StructureMap in Unity?
I like to think about a layer/component/library to configure it self - thus populating the container. So the "parent" layer will just need to know about the Registration class.

No, there isn't. In our current project we have manually mimic'd the concept of a Registry although our implementation isn't nearly as powerful as a StructureMap Registry.
If all you are wanting is modularized container configuration, what you could do is create a marker interface (maybe IRegistry) and then have your application scan for IRegistry classes. With Unity, you can resolve classes that haven't been registered into Unity yet, so you could simply resolve each IRegistry implementation as you find it. The registry classes could take the container as a constructor parameter and then each class could configure the container as needed for that layer/component/library.
public interface IRegistry
{
void Configure();
}
public class ServicesRegistry : IRegistry
{
public ServicesRegistry(IUnityContainer container)
{
_container = container;
}
public sub Configure()
{
// Configure container for layer
}
}
Now in your app startup somewhere you could have an application bootstrapper that either knows about all your registries or knows how to scan for them.

You can try UnityConfiguration which is a convention based configuration API for the Unity IoC container, heavily influenced by StructureMap
https://github.com/thedersen/UnityConfiguration

Related

Can Prism use .NET Core's built in Dependency Injection?

I'd like to start a WPF app using .NET Core 3.1
Can Prism make use of .Net Core's built-in DI (IServiceCollection) or do I have to use something like Unity?
If Prism cannot use the built-in DI, can they exist side-by-side?
Can Prism make use of .Net Core's built-in DI
From what I've seen you can't really replace Prism's DryIot with the ASP.NET Core build-in one. Mainly DryIot is more feature-full than the ServiceCollection API. There is this opensource package I've found that has an IContainerExtension implementation using ServiceCollection, but per the developer's own words this is more of a proof of concept rather than sable solution.
If Prism cannot use the built-in DI, can they exist side-by-side?
Yes, they can. With a caveat - you cannot simply register a service in ServiceCollection and expect to be able to inject that service directly in your App, Modules and ViewModels. This will fail because those files are managed by the Prism framework and thus injection will only work for services you have registered using the IContainerRegistry interface.
Benefits
Why would you do it? As the build-in IoT container the ServiceCollection API is well-known, thus it will be simpler for .Net developers. Furthermore you can structure you non-WPF projects to register services using the default container thus allowing them to be completely decoupled from your Desktop project. This is very good for more complex architectures like Domain-Driven Design.
Let's consider the following project structure:
solution
-- Desktop // Prism WPF application, containing only views and models
-- Application // Class library, containing operational logic.
Let's say that as a part of the Application project you need an IUserService which holds information about the current user that has to be populated in-memory when the user authenticates in the Desktop app. A registration method would look like this:
public IServiceCollection AddServices(this IServiceCollection services)
{
services.AddSingleton<IUserService, UserService>()
}
So now we need to inject it inside the Desktop project. I suggest two methods:
Simple
Seemless
Simple
This approach requires very simple startup configuration. The caveat is that you will not be able to inject your services directly in the constructor, but through the IServiceProvider interface.
Reference Microsoft.Extensions.DependencyInjection
Call your service registration method in App:
protected override void RegisterTypes(IContainerRegistry container)
{
// Build service provider using the ServiceCollection API
var provider = new ServiceCollection()
.AddServices()
.BuildServiceProvider();
// Register IServiceProvider within DryIot and provide
// a factory method to retrieve the service instance
container.Register<IServiceProvider>(() => provider);
}
Inject IServiceProvider where you need IUserService. For this example I'll use a Prism Module:
public class Module : IModule
{
private readonly IUserService userService;
public Module(IServiceProvider serviceProvider)
{
this.userService = serviceProvider.GetService<IUserService>();
}
...
private void Authenticate()
{
this.userService.IsAuthenticated = true;
}
}
That's it, you can now use your ServiceCollection registered dependency wherever you can access the IServiceProvider through Prism injection. This is the approach I recommend, because we are simply wrapping the .Net container in Prism's.
Seemless
This is where it gets a bit more interesting. Full disclaimer - you might encounter problems using this approach. I have not yet tested this beyond the most basic use-case. The only advantage this method offers is that you will be able to directly inject services in the constructor, instead of having to go through the IServiceProvider.
In its essence this method is simply looping through the ServiceCollection and registering all services directly in the Prism container. If we take a look at the implementation of ServiceCollection - it is simply a list of ServiceDescriptors. Upon further inspection we observe that ServiceDescriptior contains a bunch of constructors. We'll ignore those and focus on the properties:
ServiceType - the type that will be used when injecting
ImplementationType - type of the implementation to be injected
ImplementationInstance - instance of the implementation type
ImplementationFactory - factory delegate that returns an instance of the implementation type
LifeTime - Singleton, Scoped or Transient type
Let's now inspect the IContainerRegistry interface. We'll see that there are a lot of overloads of Register that accept Types, object and delegates.
Using that knowledge we can now create an adapter from ServiceDescriptor to registration of IContainerRegistry. The below implementation will only focus on Transient services, but the difference between service lifetimes is simply which registry method we call - Register for a Transient and RegisterSingleton for well Singletons.
Create and Adapter class with static method that accepts IContainerRegistry and ServiceDescriptor arguments:
public static void Register(IContainerRegistry container, ServiceDescriptor service)
{
// In case an implementation instance is provided we simply need to register it
if (service.ImplementationInstance != null)
{
containter.Register(service.ServiceType, service.ImplementationInstance);
}
// In case a factory is provided we have a bit more work.
// We need to modify it in order for it to be usable by the DryIot container
else if (service.ImlementationFactory != null)
{
var factory = service.ImplementationFactory;
var dryIotFactory = dryIotProvider =>
{
var provider = dryIotProvider.Resolve<IServiceProvider>();
return factory(provider);
};
container.Register(service.ServiceType, dryIotFactory);
}
// If no implementation or factory is provided then we simply register the
// types and let the container create the implementation instance on its own.
else
{
container.Register(service.ServiceType, service.ImplementationType);
}
}
The most tricky part here is the factory. To better understand factories in service-registration know that sometimes you may need access to other services to provide the correct implementation instance. For example if IHttpClient is registered you need to provide the IAuthorizationSerice with HttpAuthorizationService implementation instead of DesktopAuthorizationService.
Essentially we wrap the original factory method with a DryIot-compatible factory (accepts instance of DryIot container) that can supply the original factory with IServiceProvider instance.
Reference Microsoft.Extensions.DependencyInjection
Call your service registration method in App:
protected override void RegisterTypes(IContainerRegistry container)
{
var services = new ServiceCollection().AddServices()
foreach (var service in services)
{
Adapter.Register(container, service);
}
}
Inject IUserService directly in the module constructor:
public class Module : IModule
{
private readonly IUserService userService;
public Module(IUserService userService)
{
this.userService = userService;
}
}
Final thoughts
Again, I recommend the simple approach. Simplicity means lower learning curve and less room for errors. The inconvenience is minor in comparison.
Another fair warning - this is not production ready code. Especially the seemless method. I have yet to "battle-test" this implementation, but it might point you in the right direction.
If anyone has feedback/opinions I would be glad to read about it :)
Can Prism make use of .Net Core's built-in DI
Short Answer, NO
Here is a comment by #brianlagunas (The creator of Prism)
As I mentioned, we can't use IServiceProvider as we are in netstandard 1.0. The ServiceProvider and IServiceCollection is in netstandard 2.0. Also, there are a number of features that Prism needs that are to limited in the IServiceCollection implementation. Such as named instances and registrations, as well as a mutable container.
here is a comment by #dansiegel
I have spent a lot of time discussing this issue, and ultimately we cannot directly rely on IServiceProvider and IServiceCollection for a variety of reasons that extend beyond whether or not they are available.
here is the another comment also by
#brianlagunas
do I have to use something like Unity?
The ServiceCollection is "something like Unity". And, yes, you can use it with prism:
Create an IContainerExtension implementation that redirects to ServiceCollection
Derive from PrismApplicationBase and return your container extension from CreateContainerExtension

How can I execute a method by accessing autowired object in spring MVC from separate standalone java application

Let's we have a class in webapp.war (spring MVC 4.2.2.RELEASE)
public class SomeClass{
#Autowired
private MyInterface implObject;
public void method1(){
implObject.doSomething();
// statements ...
}
}
and another class in standalone.jar
public class MainClass{
public static void main(String[] args){
// want to create object of SomeClass
// or execute doSomething() ...
}
}
Note: application will be deployed in clustered environment, standalone.jar will be executed by shell script (it will be registered in crontab).
I want to schedule some job (fetch records and send to weblogic queue JMS ...), using Unix crontab. and don't want to repeat DB operation separately (in standalone.jar).
Please also suggest if I can make standalone.jar small in size.
Quartz or similar implementation is not expected in my case.
Thank you.
I solved this problem by extracting necessary part of webapp.war, into app.jar.
Scheduling and batch configured using crontab.
Used maven build tool i.e maven-shade.
Any required configuration left to spring.

In Symfony2, why is it a bad idea to inject the service container, rather than individual services?

I can't find the answer to this...
If I inject the service container, like:
// config.yml
my_listener:
class: MyListener
arguments: [#service_container]
my_service:
class: MyService
// MyListener.php
class MyListener
{
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function myFunction()
{
$my_service = $this->container->get('my_service');
$my_service->doSomething();
}
}
then it works just as well as if I do:
// config.yml
my_listener:
class: MyListener
arguments: [#my_service]
my_service:
class: MyService
// MyListener.php
class MyListener
{
protected $my_service;
public function __construct(MyService $my_service)
{
$this->my_service = $my_service;
}
public function myFunction()
{
$this->my_service->doSomething();
}
}
So why shouldn't I just inject the service container, and get the services from that inside my class?
My list of reasons why you should prefer injecting services:
Your class is dependent only on the services it needs, not the service container. This means the service can be used in an environment which is not using the Symfony service container. For example, you can turn your service into a library that can be used in Laravel, Phalcon, etc - your class has no idea how the dependencies are being injected.
By defining dependencies at the configuration level, you can use the configuration dumper to know which services are using which other services. For example, by injecting #mailer, then it's quite easy to work out from the service container where the mailer has been injected. On the other hand, if you do $container->get('mailer'), then pretty much the only way to find out where the mailer is being used is to do a find.
You'll be notified about missing dependencies when the container is compiled, instead of at runtime. For example, imagine you have defined a service, which you are injecting into a listener. A few months later, you accidentally delete the service configuration. If you are injecting the service, you'll be notified as soon as you clear the cache. If you inject the service container, you'll only discover the error when the listener fails because of the container cannot get the service. Sure, you could pick this up if you have thorough integration testing, but ... you have got thorough integration testing, haven't you? ;)
You'll know sooner if you are injecting the wrong service. For example, if you have:
public function __construct(MyService $my_service)
{
$this->my_service = $my_service;
}
But you've defined the listener as:
my_listener:
class: Whatever
arguments: [#my_other_service]
When the listener receives MyOtherService, then PHP will throw an error, telling you that it's receiving the wrong class. If you're doing $container->get('my_service') you are assuming that the container is returning the right class, and it can take a long time to figure out that its' not.
If you're using an IDE, then type hinting adds a whole load of extra help. If you're using $service = $container->get('service'); then your IDE has no idea what $service is. If you inject with
public function __construct(MyService $my_service)
{
$this->my_service = $my_service;
}
then your IDE knows that $this->my_service is an instance of MyService, and can offer help with method names, parameters, documentation, etc.
Your code is easier to read. All your dependencies are defined right there at the top of the class. If they are scattered throughout the class with $container->get('service') then it can be a lot harder to figure out.
Your code is easier to unit test. If you're injecting the service container, you've got to mock the service container, and configure the mock to return mocks of the relevant services. By injecting the services directly, you just mock the services and inject them - you skip a whole layer of complication.
Don't be fooled by the "it allows lazy loading" fallacy. You can configure lazy loading at configuration level, just by marking the service as lazy: true.
Personally, the only time injecting the service container was the best possible solution was when I was trying to inject the security context into a doctrine listener. This was throwing a circular reference exception, because the users were stored in the database. The result was that doctrine and the security context were dependent on each other at compile time. By injecting the service container, I was able to get round the circular dependency. However, this can be a code smell, and there are ways round it (for example, by using the event dispatcher), but I admit the added complication can outweigh the benefits.
Besides all disadvantages explained by others (no control over used services, run time compilation, missing dependencies, etc.)
There is one main reason, which breaks the main advantage of using DIC - Dependencies replacement.
If service is defined in library, you wont be able to replace it dependencies with local ones filling your needs.
Only this reason is strong enough, to not inject whole DIC. You just break whole idea of replacing dependencies since they are HARDCODED! in service;)
BTW. Don't forget to require interfaces in service constructor instead of specific classes as much as you can - again nice dependencies replacement.
EDIT: Dependencies replacement example
Service definition in some vendor:
<service id='vendor_service' class="My\VendorBundle\SomeClass" />
<argument type="service" id="vendor_dependency" />
</service>
Replacement in your app:
<service id='vendor_service' class="My\VendorBundle\SomeClass" />
<argument type="service" id="app_dependency" />
</service>
This allows you to replace vendor logic with your customized one, but don't forget to implement required class interface. With hardcoded dependencies you're not able to replace dependency in one place.
You can also override vendor_dependency service, but this will replace it in all places not only in vendor_service.
It is not a good idea because you're making your class dependent on the DI. What happens when some day you decide to pull out your class and use it on an entirely different project? Now I'm not talking about Symfony or even PHP, I'm talking generally. So in that case you have to make sure the new project uses the same kind of DI mechanism with the same methods supported or you get exceptions. And what happens if the project does not use DI at all, or uses some cool new DI implementation? You have to go through your whole codebase and change things to support the new DI. In large projects this can be problematic and costly, especially when you're pulling more than just one class.
It is best to make your classes as independent as possible. This means keeping the DI out of your usual code, something like a 3rd person who decides what goes where, points where the stuff should go, but doesn't go there and do it himself. This is how I understand it.
Although, as tomazahlin said, I agree that in Symfony projects in rare occasion it helps prevent circular dependencies. That's the only example where I'd use it and I'd make damn sure that's the only option.
Injecting the whole container is not a good idea in general. Well, it works, but why injecting the whole container, while you only need a few other services or parameters.
Sometimes you want to inject the whole container to avoid circular references, because if you inject the whole container, you get "lazy loading" of the services you require. An example would be doctrine entity listeners.
You can get the container from every class that is "Container Aware" or has access to the kernel.

UnitOfWork + Repository patterns and Entity Framework impersonation

I have used UnitOfWork and Repository patterns in my application with EF.
Actually my design provides that the UnitOfWork would create the ObjectContext class and inject inside the Repository concrete class. For example:
UnitOfWork.cs (initialization)
public DefaultUnitOfWork() {
if (_context == null) {
_context = new MyDataContext(ConfigSingleton.GetInstance().ConnectionString);
}
}
UnitOfWork.cs (getting a repository instance)
public CustomerRepository Customers {
get {
if (_customers == null) {
_customers = new CustomerRepository(_context);
}
return _customers;
}
}
This way the Repository classes have an already defined ObjectContext class and they can use it's methods to retrieve and update data.
This works nice.
Now I need to execute my queries impersonating the Application Pool Identity so I have decided to wrap the code in the constructor of the UnitOfWork within the impersonation.
Unfortunately this does not work because the ObjectContext is then passed to the Repository constructor and used later when a client of the repository calls, for example, FindAll().
I have experienced that the real connection to the database is made right before doing the query by Entity Framework and not exactly when I am creating the ObjectContext itself.
How can I solve this problem?
You could use one or more ObjectContext Factories (to create ObjectContexts), using different creation criteria, such as Connection String, for example. Your UnitOfWork could leverage a factory to get its Context and so could the Repository, but I think you've missed the point of UnitOfWork if it is leveraging a different ObjectContext than your Repository.
A UnitOfWork should consist of one or more operations that should be completed together, which could easily leverage multiple repositories. If the repositories have their own ObjectContexts separate from the UnitOfWork, I don't see how committing the UnitOfWork will achieve it's purpose.
I think either I've misinterpreted your question completely or you've left out some pertinent details. Good Luck!

File() FileStream in web app

I've made desktop app, and i want it to work also as an web app.
I get errors on lines with File() type and FileStream, is there any way to bypass this ?
To piggyback on #Florian F's correct response, here is how you might implement it:
Create an interface to abstract your file access
public interface IGetTheStuffService {
function getSomeTofu():Tofu;
}
Create a file-based implementation
public class FileStuffService implements IGetTheStuffService {
public function getSomeTofu():Tofu {
// File-based implementation
}
}
And an HTTP-based implementation
public class HTTPStuffService implements IGetTheStuffService {
public function getSomeTofu():Tofu {
// HTTP-based implementation
}
}
In your consumer, rely on the IGetTheStuffService
[Inject] public var tofuService:IGetTheStuffService;
public function doSomeStuff():void {
var tofu:Tofu = tofuService.getSomeTofu();
// act on the tofu
}
Notice the Inject meta tag. This is where your Dependency Injection (DI) system would push in your dependency based on the configuration (FileStuffService for Air apps or HTTPStuffService for Web apps). Parsley and RobotLegs use [Inject] where fiex-ioc uses [IocBind]
Of course, you could go without a DI container... you would just inject the parameter directly.
But you get the idea... a pretty simple pattern, actually.
The File() class is only available for AIR applications, that's why you get the error.
This is how I would do it :
You need to isolate platform dependant code and put in a separate library.
Other code that work the same whatever the platform should be in another isolated library.
Create 2 projects that will be simple wrappers. A Flex project that is only coupled to the common code. An AIR Project that is coupled to both common and platform dependant code.
You'll then probably need to use Interfaces at some time to switch between implementations that are platform specific

Resources