Loading type from new assembly using structuremap.net - inversion-of-control

I'm playing around with structuremap.net and what I'm trying to do (I'm not sure if it possible or not) is loading type implementing specific interface and this type exist in assembly that's not refrence in my application, for example i want to drop new assembly in the application directory and configure the IOC container to load , currently i'm not using a configuration file i'm just testing the concept :)
Thanks in advance

It's possible to scan all Assemblies in the application directory:
ObjectFactory.Initialize(
c => c.Scan( s =>
{
s.AssembliesFromBaseDirectory();
s.AddAllTypesOf<IMyInterface>().NameBy(type => type.Name);
})
);
or specific assemblies in a specific folder:
ObjectFactory.Initialize(
c => c.Scan( s =>
{
s.AssembliesFromPath("thePath", assembly => assembly.GetName()
.Name.Contains("Extension"));
s.AddAllTypesOf<IMyInterface>();
})
);

Related

Choose dependency for injection using Kiwi in Flutter

I have the following code:
KiwiContainer()
..registerFactory((c) => GetOrderListOfItemsUseCase(
repository: c<ShopRepository>()))
The problem here is that the GetOrderListOfItemsUseCase requires an instance of IProfileRepository which the ShopProfileRepository extends from.
NOTE: IProfleRepository is extended by IUserProfileRepository and IShopProfileRepository.
UPDATE: I have the following factories:
..registerFactory<IShopRepository>((c) => c<ShopRepository>())
..registerFactory<IUserProfileRepository>((c) => c<UserProfileRepository>())
The thing is that I want to dynamically inject the proper dependency for GetUserLocationsUseCase.
..registerFactory(
(c) => GetUserLocationsUseCase(repository: c<IProfileRepository>()))
how can I inject in the code the proper subtype of IProfileRepository whether it IShopRepository or IUserProfileRepository?
If you want to dinamically inject either UserProfileRepository or ShopProfileRepository you should register the one you are going to use via its supertype.
KiwiContainer()
..registerFactory<IProfleRepository>((c) => ShopProfileRepository())
..registerFactory((c) => GetOrderListOfItemsUseCase(
repository: c<IProfleRepository>()))
And obtain it via its supertype too, like in the snippet.

Finding full folders list of a datastore

I'm trying to get the entire folder name list of a VMWARE datastore (like folder1/folder2/datastore1, for example)
Found some code for a VM :
$vmtmp = Vim::find_entity_view(view_type => "VirtualMachine", filter => { name => $vm->name });
$path = Util::get_inventory_path($vmtmp ,Vim::get_vim());
but the find_entity_view function does not manage datastore data type.
Any clue to get this list (I'm newbie to perl sdk for vmware and a bit confused with the documentation) ?
See find_entity_view in Vim.
view_type => "Datastore"

StructureMap could not load assembly from file in a plugin framework

I'm using StructureMap to load Plugins at the start of my application. At application startup, when I create the container I do a simple scan like:
internal static IContainer Init()
{
var container = new Container(a =>
{
a.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.AssembliesFromPath($"{AppDomain.CurrentDomain.BaseDirectory}Plugins");
});
});
ConfigureDebugSubstitutions(container);
return container;
}
But I see these errors in the console:
StructureMap could not load assembly from file <filepath>
I end up getting around it currently by manually loading the files into the AppDomain like this:
private static void LoadPluginAssemblies()
{
var pluginAssemblies = Directory.GetFiles($"{AppDomain.CurrentDomain.BaseDirectory}plugins", "*.dll");
pluginAssemblies.Each(a =>
{
Assembly.LoadFile(a);
});
}
But I'm curious why I'm getting this message from structuremap to begin with. I looked at the code, and it looks like any errors are simply getting handled. Any thoughts? I'm using version 4.0.1.318 and I didn't notice this until I upgraded StructureMap from version 3.1.4.143. Also, I'm using .Net v4.6.1 if it matters.
Looks like it might have been a bug.
So, yes, I know why. It's trying to load the assembly by name directly from the AppDomain, which is really more efficient and less error prone than loading by the file path. Fine and good, but it should be trying to fallback to loading by the file in your case. I'm addressing this right now and it'll be in 4.1.
https://github.com/structuremap/structuremap/issues/451

zendframework 2 - where to save custom library folder

In Zendframework-1, we usually save the customized code under library folder (parallel to application folder) almost using the same folder structure as zend framework (vendor) library to create plugin or extend core library.
In zend framework 2, folder structure is changed. zend vendor core library is moved under Vendor folder and application folder is moved into Module (root) folder.
My question is, which is the best place to save customized plugin/code based library folder in ZF2?
Anyone else have gone through this phase?
Depends on the purpose of your library
Case 1, used by many modules:
Place it in your vendor folder, make sure to be PSR-0 compliant, that makes autoloading easy.
Case 2, used by only one module:
Place it in under modules/your_module/src and edit the Module.phps getAutoloaderConfig() method to have it autoloaded.
....
class Module {
....
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php', // classmap for production usage
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, // your module's files autoloading (development usage and fallback)
'library_namespace' => __DIR__ . '/src/librarys_namespace/potential_subfolder', // your library files autoloading (development usage and fallback). eg: 'acme' => '/src/acme/library' for acme namespace
),
),
);
}
....
Case 3, your library is 3rd party module:
Place it within the vendor folder, for references look at ZfcUser
I think your use-case would most like be case 1, your library modifies behaviour of e.g. the Zend\Mvc\Controller\AbstractActionController or additional plugins.
But if a plugin is only used by one module you'll be better of placing it parallel to your Modules code as described in Case 2.
./vendor if your code has generic purposes (i.e.: Classes like StdClass, ArrayAccess, Iterator, etc...). In short, if those Classes are required for Modules to work, they should be inside vendor.
./module In case your Plugins/Code are meant for a specific purpose (and Standalone), you may evaluate if it's a module or not (i.e.: ZF-Commons 3rd Party Modules/Plugins like ZfcUser)

Make use of AllTypes.FromAssemblyContaining() / UsingFactoryMethod()

I am registering many repositories which are located in the same assembly by using the following code:
IoCContainer.Register(AllTypes.FromAssemblyContaining<RepositoryOne>).BasedOn(typeof(IRepository<>)).WithService.AllInterfaces().Configure(c => c.LifeStyle.Singleton));
Because I want to have influence on the creation of these repositories, I am trying to use UsingFactoryMethod() with it. Using this method is simple when I register every repository separately like
IoCContainer.Register(Component.For<IRepositoryOne>().ImplementedBy<RepositoryOne>().LifeStyle.Singleton.UsingFactoryMethod(() => Factory.New<RepositoryOne>()));
...
IoCContainer.Register(Component.For<IRepositoryN>().ImplementedBy<RepositoryN>().LifeStyle.Singleton.UsingFactoryMethod(() => Factory.New<RepositoryN>()));
But how can I use UsingFactoryMethod() together with the code from the first example?
TIA
You have to use a bit of reflection to use it, since you don't have the exact type of the object you'd be resolving.
var factoryMethod = typeof(Factory).GetMethod("New", BindingFlags.Static|BindingFlags.Public);
container.Register(
AllTypes.FromAssemblyContaining<RepositoryOne>)
.BasedOn(typeof(IRepository<>))
.WithService.AllInterfaces()
.Configure(x => x.UsingFactoryMethod((k, c) => factoryMethod.MakeGenericMethod(c.RequestedType).Invoke(null, null)));