AutoFac IRegistrationBuilder - autofac

I am new to Autofac and IOC concept. I have following code which I am not getting or understanding what it is doing.
`
public void AddComponentInstance<TService>(object instance, string key = "", ComponentLifeStyle lifeStyle = ComponentLifeStyle.Singleton)
{
AddComponentInstance(typeof(TService), instance, key, lifeStyle);
}
public void AddComponentInstance(Type service, object instance, string key = "",ComponentLifeStyle lifeStyle = ComponentLifeStyle.Singleton)
{
UpdateContainer(x =>
{
var registration = x.RegisterInstance(instance).Keyed(key, service).As(service).PerLifeStyle(lifeStyle);
});
}
public void UpdateContainer(Action<ContainerBuilder> action)
{
var builder = new ContainerBuilder();
action.Invoke(builder);
builder.Update(_container);
}
public static class ContainerManagerExtensions
{
public static Autofac.Builder.IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> PerLifeStyle<TLimit, TActivatorData, TRegistrationStyle>(this Autofac.Builder.IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> builder, ComponentLifeStyle lifeStyle)
{
switch (lifeStyle)
{
case ComponentLifeStyle.LifetimeScope:
return HttpContext.Current != null ? builder.InstancePerHttpRequest() : builder.InstancePerLifetimeScope();
case ComponentLifeStyle.Transient:
return builder.InstancePerDependency();
case ComponentLifeStyle.Singleton:
return builder.SingleInstance();
default:
return builder.SingleInstance();
}
}
}
`
From above code what I understood is that, We are registering the Singleton Instance in Container and we are updating the container. I searched online For IRegistrationBuilder interface example but I could not get any satisfying answer.
Can anyone please help me to understand the concept of IRegistrationBuilder.
I am referring this code from NopCommerce application.
Thanks in Advance.

IRegistrationBuilder is application of builder design pattern within autofac. Look at the line:
x.RegisterInstance(instance).Keyed(key, service).As(service).PerLifeStyle(lifeStyle);
this chain of methods defines registration of istance of certain object. Each of the methods used sets properties used for proper registration. Each of the methods returns builder object which implements IRegistrationBuilder - it holds all those properties. Because PerLifeStyle accepts as first parameter IRegistrationBuilder you can use it in chain above to change builder properties - in case of PerLifeStyle to affect instantiation of the object. Because PerLifeStyle returns IRegistrationBuilder you may use it in the middle of methods invokation chain like:
x.RegisterInstance(instance).PerLifeStyle(lifeStyle).Keyed(key, service).As(service)

Related

aspnetboilerplate EventCloud example - design pattern

in this tutorial about the EventCloud example app:
https://aspnetboilerplate.com/Pages/Documents/Articles/Developing-MultiTenant-SaaS-ASP.NET-CORE-Angular/index.html
the text states: the creation of a new entity must be done using the static method "Create" in the "Event" class (not using "new Entity(....)")
1) so my first question is: which design pattern is this? Factory? Builder? other?
[Table("AppEvents")]
public class Event : FullAuditedEntity<Guid>, IMustHaveTenant
{
......
....
...
/// <summary>
/// We don't make constructor public and forcing to create events using <see cref="Create"/> method.
/// But constructor can not be private since it's used by EntityFramework.
/// Thats why we did it protected.
/// </summary>
protected Event()
{
}
public static Event Create(int tenantId, string title, DateTime date, string description = null, int maxRegistrationCount = 0)
{
var #event = new Event
{
Id = Guid.NewGuid(),
TenantId = tenantId,
Title = title,
Description = description,
MaxRegistrationCount = maxRegistrationCount
};
#event.SetDate(date);
#event.Registrations = new Collection<EventRegistration>();
return #event;
}
....
...
2) the second question:
than the article says...
Event Manager .... All Event operations should be executed using this class... (EventManager)
ok, the CreateAsync method call the repository insert method, is the static "Event.Create" internaly called from the repository insert method? if yes, could you indicate me the point in the abp source code?
or is it an internal matter of EntityFramework?
public class EventManager : IEventManager
{
......
....
..
public async Task CreateAsync(Event #event)
{
await _eventRepository.InsertAsync(#event);
}
Here are my answers:
1-) Event is being created with a static factory method. There are 2 ways to create an entity in Domain Driven Design.
Creating with static factory methods: It's a convenient way of creating business entities. And this method is being used in EventCloud. The only downside of this method is it's static! If your entity is holding state it's not good for testability. But there are 3 advantages of this approach;
They have names: for example Event.CreatePublicEvent(), Create.PrivateEvent()
They can cache: You can cache them in a private static HashSet or Dictionary.
They can subtype.
Creating with a constructor: If you have only one constructor then creating an object through its public constructor is the most convenient approach in Domain Driven Design. As long as you make parameterless constructor protected or private. Besides, an entity should be responsible for its own data integrity and validity so you have to set all business related public properties as private setter and you should allow them to change through public methods.
Further information, see https://www.yegor256.com/2017/11/14/static-factory-methods.html
2-) EventManager is a domain service that is used for business logic. And Event.Create() is being used in the EventAppService class. Click here to see where exactly is being executed. Even Event.Create() method consists of a single line of code but it's open for extension.
I hope that will be useful ;)
Happy coding...

How to Unittest a Factory with dependencies

How can I test my factory with the entity manager? I have an error because I need to make my container return an instance of a class created from doctrine ( I do not even know what there is returned).
How can I create a test that I can make pass?
// factory i want to test
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$googleAppOption = $container->get(GoogleAppOptions::class);
$em = $container->get('doctrine.entity_manager.orm_default');
return new GoogleTokenHandler($googleAppOption, new GoogleTokenClient(), $em);
}
//test function
public function testReturnsTokenHandlerInstance()
{
$googleOptionsFactory = new GoogleOptionsFactory();
$googleOptions = $googleOptionsFactory($this->container->reveal(), null);
$this->container->get(GoogleAppOptions::class)->willReturn($googleOptions);
$googleTokenHandlerFactory = new GoogleTokenHandlerFactory($this->container);
$tokenHandler = $googleTokenHandlerFactory($this->container->reveal(), null);
$this->assertInstanceof(GoogleTokenHandler::class, $tokenHandler);
}
Th fact that this is hard to test is a good sign that there is something smelly about this. In your case it's quite obviously the container being injected and then being used to locate services to work upon. I would recommend rewriting this class to inject both the OptionsFactory (or even better just the options) and the EntityManager as well as the dynamically created GoogleClient in the constructor. What you would arrive at is an invoke that pretty much looks like this:
return new GoogleTokenHandler(
$this->optionsFactory,
$this->tokenClient,
$this->entityManager
);
As you can see you neither use the $requestedName nor the optional $options being passed to your __invoke. That's a bit odd, but that won't bother us with the tests. Now you can simply mock out the services in your test and check whether invoke returns the correct instance:
public function testFactoryInvokeReturnsInstance()
{
$optionsFactory = $this->prophesize(OptionsFactory::class);
$tokenClient = $this->prophesize(GoogleTokenClient::class);
$entityManager = $this->prophesize(EntityManager::class);
$factory = new MyFactory(
$optionsFactory->reveal(),
$tokenClient->reveal(),
$entityManager->reveal()
);
$this->assertInstanceOf(GoogleTokenHandler::class, $factory->__invoke());
// Alternatively you can use the __invoke-magic directly:
$this->assertInstanceOf(GoogleTokenHandler::class, $factory());
}
You could do the same with your class but basically you would have to add a Container and then stub out the get-method for all of the services being fetched from it. For example you are missing the entity manager in your snippet. Should the GoogleTokenClient being created in your method require some arguments/options there is no way to mock that behavior and in fact you won't be able to switch it out without changing the code. Whereas by injecting it in the constructor you can just re-configure your container to pass in a different object.
For posterity, your complete factory would probably look something like this:
class Factory {
private $optionsFactory;
private $tokenClient;
private $entityManager;
public function __construct(GoogleTokenClient $tokenClient, ...)
{
$this->tokenClient = $tokenClient;
...
}
public function __invoke() { return new GoogleTokenHandler(...); }
}

Autofac inspect lifetime scope of type being resolved

I am writing a adapter around autofac, and need to provide an implementation of:
T ResolveSingleton<T>()
where this method will return an instance if and only if the type was registered with singleton lifetime, otherwise it will throw an error.
I am new to autofac and was wondering if there is a way to query the container for the registered lifetime of a type?
Thanks!
Looking at the Autofac source code, you'll can see that the implementation of SingleInstance is this:
public IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> SingleInstance()
{
RegistrationData.Sharing = InstanceSharing.Shared;
RegistrationData.Lifetime = new RootScopeLifetime();
return this;
}
So you'll have to check the ComponentRegistry for registrations matching those qualities.
public T ResolveSingleton<T>()
{
IComponentRegistration reg;
if (_context.ComponentRegistry.TryGetRegistration(new TypedService(typeof (T)), out reg))
{
if (reg.Lifetime is RootScopeLifetime && reg.Sharing == InstanceSharing.Shared)
return (T) _context.ResolveComponent(reg, Enumerable.Empty<Parameter>());
}
throw new Exception();
}

How to resolve generic type at runtime

I'm trying to build a command processor that can take any command that implements a marker interface (or maybe descends from a base class). The processor will handle the command that it is asked to process. However I'm struggling with resolving the true generic type as Resolve(Type) returns an object.
I'm not sure is how to cast this if at all possible?
public void Process(ICommand command)
{
var c = command.GetType();
var t = typeof(ICommandHandler<>).MakeGenericType(new[] { c });
var o = container.Resolve(t);
//((ICommandHandler)o).Handle(command); *** This doesn't work
}
The calling code would be something like this -
Dispatcher.Process(new SomeCommand(Guid.NewGuid(),"Param1",12345));
If you absolutely have to call the ICommandHandler<T>.Handle method and you have no other control over the design of the system, then reflection may be your only choice. There's no great way to deal with the switch from generic to non-generic.
Otherwise, you may have a couple of options.
First, if your Dispatcher.Process can be made generic, you can save all the casting.
public static class Dispatcher
{
public static void Process<T>(T command) where T : ICommand
{
var handler = container.Resolve<ICommandHandler<T>>();
handler.Handle(command);
}
}
This is a pretty common solution to a problem like this that I've seen out in the wild.
If you can't do that, then you may be able to make your ICommandHandler<T> interface implement a non-generic ICommandHandler base interface.
public interface ICommandHandler
{
void Handle(ICommand command);
}
public interface ICommandHandler<T> : ICommandHandler
{
void Handle(T command);
}
In this latter case you'd have to switch your strongly-typed command handler implementations to call the same internal logic for generic or basic handling or you'll get different handling based on the call, which would be bad:
public class SomeCommandHandler : ICommandHandler<SomeCommand>
{
public void Handle(ICommand command)
{
var castCommand = command as SomeCommand;
if(castCommand == null)
{
throw new NotSupportedException("Wrong command type.");
}
// Hand off to the strongly-typed version.
this.Handle(castCommand);
}
public void Handle(SomeCommand command)
{
// Here's the actual handling logic.
}
}
Then when you resolve the strongly-typed ICommandHandler<T> your cast down to ICommandHandler (as shown in your question's sample code) will work.
This is also a pretty common solution, but I've seen it more in systems that existed before generics were available where an updated API was being added.
However, in all cases here, the problem really isn't that Autofac is returning an object; it's a class/type design problem that affects any generic-to-non-generic conversion scenario.
Using Reflection - but is this the best way to approach this?
public void Process(Command command)
{
var c = command.GetType();
var ot = typeof(ICommandHandler<>);
var type = ot.MakeGenericType(new[] { c });
var mi = type.GetMethod("Handle");
var o = container.Resolve(type);
mi.Invoke(o, new object[] { command });
}

Why does getting the nth child of a Node fail in an ExplorerManager listener?

I'm having problems with the NetBeans Nodes API.
I have this line of code:
Node n = (new MyNode(X)).getChildren().getNodeAt(Y);
The call to new MyNode(X) with the same X always initializes a MyNode the same way, independent of the context.
When I place it by itself (say, in an menu action), it successfully gets the Yth child, but if I put it in an event where other Node/Children stuff happens, it returns null.
MyNode's Children implementation is a trivial subclass of Children.Keys, which is approximately:
// Node
import org.openide.nodes.AbstractNode;
class MyNode extends AbstractNode {
MyNode(MyKey key) {
super(new MyNodeChildren(key));
}
}
// Children
import java.util.Collections;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
public class MyNodeChildren extends Children.Keys<MyKey> {
MyKey parentKey;
MyNodeChildren(MyKey parentKey) {
super(true); // use lazy behavior
this.parentKey = parentKey;
}
#Override
protected Node[] createNodes(MyKey key) {
return new Node[] {new MyNode(key)};
}
#Override
protected void addNotify() {
setKeys(this.parentKey.getChildrenKeys());
}
#Override
protected void removeNotify() {
setKeys(Collections.EMPTY_SET);
}
}
// MyKey is trivial.
I assume this has something to do with the lazy behavior of Children.Keys. I have the sources for the API, and I've tried stepping through it, but they're so confusing that I haven't figured anything out yet.
NetBeans IDE 7.0.1 (Build 201107282000) with up-to-date plugins.
Edit: More details
The line with the weird behavior is inside a handler for an ExplorerManager selected-nodes property change. The weird thing is that it still doesn't work when the MyNode instance isn't in the heirarchy that the ExplorerManager is using (it's not even the same class as the nodes in the ExplorerManager), and isn't being used for anything else.
Accessing the nodes instead of the underlying model is actually necessary for my use case (I need to do stuff with the PropertySets), the MyNode example is just a simpler case that still has the problem.
It is recommended to use org.openide.nodes.ChildFactory to create child nodes unless you have a specific need to use one of the Children APIs. But for the common cases the ChildFactory is sufficient.
One thing to keep in mind when using the Nodes API is that it is only a presentation layer that wraps your model and used in conjunction with the Explorer API makes it available to the various view components in the NetBeans platform such as org.openide.explorer.view.BeanTreeView.
Using a model called MyModel which may look something like:
public class MyModel {
private String title;
private List<MyChild> children;
public MyModel(List<MyChild> children) {
this.children = children;
}
public String getTitle() {
return title;
}
public List<MyChild> getChildren() {
return Collections.unmodifiableList(children);
}
}
You can create a ChildFactory<MyModel> that will be responsible for creating your nodes:
public class MyChildFactory extends ChildFactory<MyModel> {
private List<MyModel> myModels;
public MyChildFactory(List<MyModel> myModels) {
this.myModels = myModels;
}
protected boolean createKeys(List<MyModel> toPopulate) {
return toPopulate.addAll(myModels);
}
protected Node createNodeForKey(MyModel myModel) {
return new MyNode(myModel);
}
protected void removeNotify() {
this.myModels= null;
}
}
Then, implementing MyNode which is the presentation layer and wraps MyModel:
public class MyNode extends AbstractNode {
public MyNode(MyModel myModel) {
this(myModel, new InstanceContent());
}
private MyNode(MyModel myModel, InstanceContent content) {
super(Children.create(
new MyChildrenChildFactory(myModel.getChildren()), true),
new AbstractLookup(content)); // add a Lookup
// add myModel to the lookup so you can retrieve it latter
content.add(myModel);
// set the name used in the presentation
setName(myModel.getTitle());
// set the icon used in the presentation
setIconBaseWithExtension("com/my/resouces/icon.png");
}
}
And now the MyChildrenChildFactory which is very similar to MyChildFactory except that it takes a List<MyChild> and in turn creates MyChildNode:
public class MyChildFactory extends ChildFactory<MyChild> {
private List<MyChild> myChildren;
public MyChildFactory(List<MyChild> myChildren) {
this.myChildren = myChildren;
}
protected boolean createKeys(List<MyChild> toPopulate) {
return toPopulate.addAll(myChildren);
}
protected Node createNodeForKey(MyChild myChild) {
return new MyChildNode(myChild);
}
protected void removeNotify() {
this.myChildren = null;
}
}
Then an implementation of MyChildNode which is very similar to MyNode:
public class MyChildNode extends AbstractNode {
public MyChildNode(MyChild myChild) {
// no children and another way to add a Lookup
super(Children.LEAF, Lookups.singleton(myChild));
// set the name used in the presentation
setName(myChild.getTitle());
// set the icon used in the presentation
setIconBaseWithExtension("com/my/resouces/child_icon.png");
}
}
And we will need the children's model, MyChild which is very similar to MyModel:
public class MyChild {
private String title;
public String getTitle() {
return title;
}
}
Finally to put it all to use, for instance with a BeanTreeView which would reside in a TopComponent that implements org.openide.explorer.ExplorerManager.Provider:
// somewhere in your TopComponent's initialization code:
List<MyModel> myModels = ...
// defined as a property in you TC
explorerManager = new ExplorerManager();
// this is the important bit and we're using true
// to tell it to create the children asynchronously
Children children = Children.create(new MyChildFactory(myModels), true);
explorerManager.setRootContext(new AbstractNode(children));
Notice that you don't need to touch the BeanTreeView and in fact it can be any view component that is included in the platform. This is the recommended way to create nodes and as I've stated, the use of nodes is as a presentation layer to be used in the various components that are included in the platform.
If you then need to get a child you can use the ExplorerManager which you can retrieve from the TopComponent using the method ExplorerManager.Provier.getExplorerManager() which was implemented due to the fact that your TopComponent implemented ExplorerManager.Provider and is in fact the way that a view component itself gets the nodes:
ExplorerManager explorerManager = ...
// the AbstractNode from above
Node rootContext = explorerManager.getRootContext();
// the MyNode(s) from above
Children children = rootContext.getChildren().getNodes(true);
// looking up the MyModel that we added to the lookup in the MyNode
MyModel myModel = nodes[0].getLookup().lookup(MyModel.class);
However, you must be aware that using the Children.getNodes(true) method to get your nodes will cause all of your nodes and their children to be created; which weren't created due to the fact that we told the factory that we wanted it to create the children asynchronously. This is not the recommended way to access the data but instead you should keep a reference to the List<MyModel> and use that if at all possible. From the documentation for Children.getNodes(boolean):
...in general if you are trying to get useful data by calling this method, you are probably doing something wrong. Usually you should be asking some underlying model for information, not the nodes for children.
Again, you must remember that the Nodes API is a presentation layer and is used as an adapter between your model and your views.
Where this becomes a powerful technique is when using the same ChildFactory in different and diverse views. You can reuse the above code in many TopComponents without any modifications. You can also use a FilterNode if you need to change only a part of the presentation of a node without having to touch the original node.
Learning the Nodes API is one of the more challenging aspects of learning the NetBeans platform API as you have undoubtedly discovered. Once you have some mastery of this API you will be able to take advantage of much more of the platforms built in capabilities.
Please see the following resources for more information on the Nodes API:
NetBeans Nodes API Tutorial
Great introduction to the Nodes API by Antonio Vieiro
Part 5: Nodes API and Explorer & Property Sheet API by Geertjan Wielenga
JavaDocs for the Nodes API
Timon Veenstra on the NetBeans Platform Developers mailing list solved this for me.
Actions on the explorerManager are guarded to ensure consistency. A
node selection listener on an explorer manager for example cannot
manipulate the same explorer manager while handling the selection
changed event because that would require a read to write upgrade. The
change will be vetoed and die a silent death.
Are you adding the MyNode root node to the explorer manager on
initialization, or somewhere else in a listener?
My problem line is in an ExplorerManager selection change listener. I guess the Children.MUTEX lock is getting set by ExplorerManager and preventing the Children.Keys instance from populating its Nodes...?
Anyways, I moved my Node access into a EventQueue.invokeLater(...), so it executes after the selection changed event finishes, and that fixed it.