MvxSimpleIoCContainer and multiple concrete implementations - mvvmcross

If I have interface IMvxScreen and multiple concrete classes that implement IMvxScreen, is it possible to resolve all implementations at once?
public MyClass(IScreen[] screens)
{

No - this isn't currently possible.
You would have to provide a separate interface/object - e.g. an IScreenService.
Assuming all your screens are in the same Assembly, I guess you could provide this using a service like:
public interface IScreenService
{
IEnumerable<IScreen> CreateAll();
}
public class ScreenService : IScreenService
{
public IEnumerable<IScreen> CreateAll()
{
return this.GetType().Assembly
.CreatableTypes()
.Inherits<IScreen>()
.Select(t => Mvx.IocConstruct(t));
}
}

Related

Creating a function a function with an unknown variable type

I'm writing a little game in processing and using custom classes to define various objects that appear on the screen.
What I have here is not a problem really, it's just something that's been bugging me.
Take this code:
void blitBalckHoles () { //idealy, it would be nice to have both of these as one function, however I don't know how to make it so that it could accept any variable type as a parameter
for (BlackHole blackHole : blackHoles) {blackHole.blit();}
}
void blitStars() {
for (Star star : stars) {star.blit();}
}
Basically my question is commented in that first line of code.
Is there anyway I can make one function that blits the parameter to matter what type it is?
What you're looking for is called an interface.
You would define a Blittable interface that contains a blit() function:
interface Blittable{
public void blit();
}
You would then create classes implement that interface by using the implements keyword and implementing the blit() function:
class Star implements Blittable{
public void blit(){
println("Star blitting.");
}
}
class BlackHole implements Blittable{
public void blit(){
println("Black Hole blitting.");
}
}
Then you could pass around instances of Star and BlackHole as Blittable references. Since any class that implements the Blittable interface must define a blit() function, you can then call the blit() function on any Blittable reference:
for(Blittable b : blitters){
b.blit();
}
Putting it all together, it looks something like this:
void setup(){
Star star = new Star();
BlackHole blackHole = new BlackHole();
ArrayList<Blittable> blitters = new ArrayList<Blittable>();
blitters.add(star);
blitters.add(blackHole);
for(Blittable b : blitters){
b.blit();
}
}
interface Blittable{
public void blit();
}
class Star implements Blittable{
public void blit(){
println("Star blitting.");
}
}
class BlackHole implements Blittable{
public void blit(){
println("Black Hole blitting.");
}
}
Note that you might also just want to use JavaScript mode, since the typing is much less strict that way.

Setting lifetime manager for registrations done using UnityConfiguration scanner

I have a ASP.NET MVC4 application and am using Unity for IOC. I am using Unity.MVC4 and UnityConfiguration Nuget packages to help with the registration.
I need to automatically register a load of interfaces and their related types to the Unity container. To do this I created a dummy interface; IDependencyInjectionScanner that all my real interfaces inherit from. Below is the code showing that.
public interface IDependencyInjectionScanner
{
}
public interface IChair : IDependencyInjectionScanner
{
NumberOfLegs { get; set; }
}
public class Chair : IChair
{
public NumberOfLegs { get; set; }
}
public interface ITable : IDependencyInjectionScanner
{
NumberOfChairs { get; set; }
}
public class Table : ITable
{
public NumberOfChairs { get; set; }
}
I then used UnityConfiguration to bind the registrations using the scanner. I have get the interfaces being correctly resolved in the controller. Below is the code that shows how I did the binding.
Scan(scan =>
{
scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
scan.With<FirstInterfaceConvention>();
scan.Include(x => (x.GetInterface(typeof(IDependencyInjectionScanner).Name) != null));
scan.ForRegistries();
});
The problem is that I want to register all the types found by the scanner using the hierarchical lifetime manager but can figure out how to do this. The GitHub page for UnityConfiguration https://github.com/thedersen/UnityConfiguration states that this could be achieved by the code below:
Configure<IChair>().AsHierarchicalControlled();
However I if I have to do that for each of the interfaces bound by the scanner then the scanner is of no use as I may as well do:
Register<IChair, Chair>().AsHierarchicalControlled();
Can someone assist me with finding a solution to this please.
Here's an answer to your question using UnityConfiguration. You can create a custom convention to configure the lifetime. Just be careful because it looks like the calls within the Scan() method are order dependent.
public class HierarchicalLifetimeConvention : IAssemblyScannerConvention
{
public void Process(Type type, IUnityRegistry registry)
{
registry.Configure(type).AsHierarchicalControlled();
}
}
and then add that to your Scan() call...
Scan(scan =>
{
scan.AssembliesInDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
scan.With<FirstInterfaceConvention>();
scan.With<HierarchicalLifetimeConvention>(); //<-- New convention
scan.Include(x => (x.GetInterface(typeof(IDependencyInjectionScanner).Name) != null));
scan.ForRegistries();
});
As suggested by #TylerOhlsen I used the built-in Registration by Convention feature of Unity 3.0. I have got it to add the registration mappings and they are using the hierarchical lifetime manager. below is the code for that
container.RegisterTypes(
AllClasses.FromLoadedAssemblies().Where(
t => t.GetInterface(typeof(IDependencyInjectionScanner).Name) != null),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.Hierarchical);
There is one thing that is disturbing me; when I look at the registrations I have 4 (based on the example code above). 2 type mappings for the Chair type and 2 type mappings for the Table type.
Can anyone shed any light on why this is, as I was only expecting two mappings.

Register interfaces with no concrete implementations to return a generated type/proxy

I want to auto register all interfaces which name ends with "Service" and also doesn't have concrete implementations to be resolved to a generated type/proxy (which off course differs per interface).
So when I want to resolve IContractService I want it to return a proxied object. I got this idea from this article where they implemented it in some way with Castle Windsor.
What would be the structuremap approach for achieving this. I tried all kind of things with custom conventions and all but I can't get my head around it.
I fixed this by using Castle's Dynamic Proxy and a StructureMap convention. BTW. I also renamed some of the classes mentioned in the article.
public class InfraRegistry : Registry
{
public InfraRegistry()
{
For<IClientProviderFactory>().Use<WcfClientProviderProviderFactory>();
Scan(scan =>
{
scan.AssemblyContainingType<MidleWareServiceConvention>();
scan.Convention<MidleWareServiceConvention>();
});
}
}
public class MidleWareServiceConvention : IRegistrationConvention
{
private readonly ProxyGenerator _proxyGen = new ProxyGenerator();
public void Process(Type type, Registry registry)
{
if (type.IsInterface && type.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase))
{
registry.For(type)
.HybridHttpOrThreadLocalScoped()
.Use(
context =>
_proxyGen.CreateInterfaceProxyWithoutTarget(type,
new WcfInterceptor(
context.GetInstance<IClientProviderFactory>())));
}
}
}

Hibernate mapping of an Enum which implements an interface (i.e. is a subclass)

I'm getting my feet wet with Hibernate, and I've run into a problem which I can't find any solution to.
I have an interface MyInterface and an enum implementing the interface:
class MyInterface {
void someMethod();
}
enum MyEnum implements MyInterface {
INST1, INST2;
#Override
public void someMethod() {
// ...
}
}
(I also have a few other implementations of MyInterface but I don't think that matters.)
Now I'm trying to map the implementations of MyInterface (where MyEnum is one of them) using the one table per class hierarchy scheme. I know how to map ordinary enums as properties, and I know how to map ordinary subclasses, but I don't know how to do the combo. Mixing the two techniques as follows
-- DOES NOT WORK. --
<subclass name="package.MyEnum" extends="package.MyInterface">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">package.MyEnum</param>
</type>
</subclass>
is apparently not supported.
Any help appreciated.
(I realize that I could work around the problem by creating something like
class MyEnumWrapper implements MyInterface {
MyEnum inst;
public void someMethod() {
inst.someMethod();
}
}
in which case an ordinary subclass-mapping would do, but I'd rather avoid this if possible. I have no problem implementing custom UserTypes though.)

Registering the same classes with two services - in two steps - in Castle Windsor

I have some executor-classes that implements one or two interfaces (IHandleMessages<> and/or CommandExecutor<>).
Can I register all these executor classes - with whichever interface(s) it implements of the two - as services. Without ending up having all other interfaces on the class as services too.
My initial attempt was this:
public class Test
{
[Fact]
public void SomeTest()
{
var container = new WindsorContainer();
container.Register(Classes.FromThisAssembly().BasedOn(typeof(CommandExecutor<>)).WithService.Base().LifestyleTransient(),
Classes.FromThisAssembly().BasedOn(typeof(IHandleMessages<>)).WithService.Base().LifestyleTransient());
container.ResolveAll<CommandExecutor<object>>().Count().ShouldBe(2);
container.ResolveAll<IHandleMessages<object>>().Count().ShouldBe(2);
}
public interface IHandleMessages<T> { }
public interface CommandExecutor<T> { }
public class HandlesMessagesOnly : IHandleMessages<object> { }
public class HandlesMessagesAndExecutesCommands : CommandExecutor<object>, IHandleMessages<object> { }
public class ExecutesCommandsOnly : CommandExecutor<object> { }
}
But that does not work. Is there a solution for this?
I'm using Windsor 3.1.0.
EDIT: I guess what I'm really asking is: Is it possible to find the same type twice, and just have the discoverer add more services to that type's registration?
This will make your test pass:
container.Register(
Classes
.FromThisAssembly()
.BasedOn(typeof(CommandExecutor<>))
.WithServiceBase()
.WithServiceFirstInterface() // Ensures first interface is included.
.LifestyleTransient(),
Classes
.FromThisAssembly()
.BasedOn(typeof(IHandleMessages<>))
.WithServiceBase()
.LifestyleTransient()
);
For more sophisticated interface selection techniques see this question.
I've made a pull request to Windsor which was accepted in 3.2, and you can now do this:
Container.Register(
Classes.FromThisAssembly()
.BasedOn<IFoo>()
.OrBasedOn(typeof(IBar))
.WithServiceBase()
.LifestyleTransient());
Read more here