tldr: Is there any way I can choose which constructor to use when I register a type?
I have followed the instructions to create a platform specific inversion of control as outlined in Inversion of control.
In your core project, you can declare an interface and you can use
that interface in your classes there ...
In each UI project, you can then declare the platform-specific
implementation ...
You can then register these implementations in each of the
platform-specific Setup files - e.g. you could override
MvxSetup.InitializeFirstChance
So in my core project I have defined the following interface
public interface IJob
{
void AddAction(Action action);
}
In my Android project I have implemented the interface as follows
public class CustomJob: Job, IJob
{
private Action _action;
public CustomJob(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public CustomJob() : base(new Params
(Jobs.Priority.MID
).RequireNetwork().Persist())
{
//_action = action;
}
public override void OnAdded()
{
}
protected override void OnCancel(int p0, Throwable p1)
{
}
public override void OnRun()
{
_action.Invoke();
}
protected override RetryConstraint ShouldReRunOnThrowable(Throwable p0, int p1, int p2)
{
return RetryConstraint.Cancel;
}
public void AddAction(Action action)
{
_action = action;
}
}
And I overrode the implementation of InitializeFirstChance in Setup.cs
protected override void InitializeFirstChance()
{
Mvx.IoCProvider.RegisterType<IJob, CustomJob>();
base.InitializeFirstChance();
}
However, I get the following stacktrace at runtime
{MvvmCross.Exceptions.MvxIoCResolveException: Failed to resolve
parameter for parameter javaReference of type IntPtr when creating
CustomJob. You may pass it as an argument at
MvvmCross.IoC.MvxIoCContainer.GetIoCParameterValues (System.Type type,
System.Reflection.ConstructorInfo firstConstructor,
System.Collections.Generic.IDictionary2[TKey,TValue] arguments)
[0x0005a] in
C:\projects\mvvmcross\MvvmCross\IoC\MvxIoCContainer.cs:648 at
MvvmCross.IoC.MvxIoCContainer.IoCConstruct (System.Type type,
System.Collections.Generic.IDictionary2[TKey,TValue] arguments)
[0x00031] in
C:\projects\mvvmcross\MvvmCross\IoC\MvxIoCContainer.cs:413
Is there any way I can choose which constructor to use when I register a type? Thank you.
AFAIK you can't choose which constructor the Mvx's IoC engine will choose.
So one way is to make another class that implements your IJob that has a reference to Job internally and in the implementation of the class you pass the action to the Job implementation.
public class JobHandler : IJob
{
private Job _customJob;
public JobHandler()
{
this._customJob = new CustomJob();
}
public void AddAction(Action action)
{
this._customJob.AddAction(action);
}
}
If you want you can do an IJobHandler that inherits IJob so that you can use that interface for the JobHandler implementations and the IJob for you actual Job
Another way is to add stub parameters to the parameterless constructor so that it takes more parameters than the other and gets elected by the IoC engine (I'm not entirely sure that it would work, but I think so). But it is a bit messy.
Another way is you to tell the IoC engine how you want to construct your IJob:
Mvx.IoCProvider.RegisterType<IJob>(() => new CustomJob());
HIH
Related
Recently I have worked with asp.net mvc and I have seen in sample project is using Database Factory class. How can you explain for me why use it ?
IDatabaseFactory class
public interface IDatabaseFactory : IDisposable
{
EFMVCDataContex Get();
}
DatabaseFactory class
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private EFMVCDataContex dataContext;
public EFMVCDataContex Get()
{
return dataContext ?? (dataContext = new EFMVCDataContex());
}
protected override void DisposeCore()
{
if (dataContext != null)
dataContext.Dispose();
}
}
This is an example of an Abstract Factory design pattern. The idea is to create a seam to provide loose coupling between the classes so another type of context could be swapped, either for testing purposes or to extend the application.
Generally speaking, a factory is a way to manage short-lived dependencies, such as database connections. Typically, a framework exposes a way to inject an instance of the factory and then the framework can work with it based on an interface (in this case IDatabaseFactory) as a contract between the framework, and the framework user. The framework will have code that looks something like this:
public interface ISomeService
{
void DoSomething();
}
public class SomeService()
{
private readonly IDatabaseFactory factory;
// The factory is injected through the constructor
public SomeService(IDatabaseFactory factory)
{
this.factory = factory;
}
public void DoSomething()
{
using (EFMVCDataContex context = this.factory.Get())
{
// Run a LINQ query here using the context
} // This bracket disposes the context
}
}
The service can then be instantiated for a much longer lifetime than the context that is created by the factory. What's more is that the context is always properly disposed in this scenario.
Now, the main benefit from doing this is that you can swap the DatabaseFactory with an alternate implementation (commonly referred to as the Liskov Substitution Principle):
public class MyDatabaseFactory : Disposable, IDatabaseFactory
{
private EFMVCDataContex dataContext;
public EFMVCDataContex Get()
{
return dataContext ?? (dataContext = new AlternateDataContext());
}
protected override void DisposeCore()
{
if (dataContext != null)
dataContext.Dispose();
}
}
Assuming that AlternateDataContext inherits (or implements) EFMVCDataContex, MyDatabaseFactory can be swapped apples-for-apples with DatabaseFactory without making any changes to SomeService.
MyDatabaseFactory could be coded with a connection string in the constructor, giving you a way to connect to alternate databases, for example.
Of course, another great benefit of doing this is to create a mock implementation of IDatabaseFactory that can be used to test the DoSomething method. In a unit test, SomeService (the class under test) should be the only real class being used, IDatabaseFactory should be a mock (which could either be done by hand coding a class, or using a mocking framework).
Preliminaries
I'm using Ninject.MVC3 2.2.2.0 Nuget Package for injecting into my controller an implementation of a IDomain Interface that separates my Business Logic (BL) using an Factory approach.
I'm registering my Ninject Modules in the preconfigured NinjectMVC3.cs using:
private static void RegisterServices(IKernel kernel)
{
var modules = new INinjectModule[]
{
new DomainBLModule(),
new ADOModule()
};
kernel.Load(modules);
}
I'm trying to avoid the fatal curse of the diabolic Service Locator anti-pattern.
The Domain Class uses a DBContext that i'm trying to inject an interface implementation too, via an IDBContext, with the following scenario:
IDomainBLFactory:
public interface IDomainBLFactory
{
DomainBL CreateNew();
}
DomainBLFactory:
public class DomainBLFactory : IDomainBLFactory
{
public DomainBL CreateNew()
{
return new DomainBL();
}
}
In the controller's namespace:
public class DomainBLModule : NinjectModule
{
public override void Load()
{
Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
}
}
At this point i can inject the IDomainBLFactory implementation into my controller using Ninject Constructor Injection without any problem:
public class MyController : Controller
{
private readonly IDomainBLFactory DomainBLFactory;
// Default Injected Constructor
public MyController(IDomainBLFactory DomainBLFactory)
{
this.DomainBLFactory = DomainBLFactory;
}
... (use the Domain for performing tasks/commands with the Database Context)
}
Now my central problem.
In the DomainBL implementation, i will inject the dependency to a particular DBContext, in this case ADO DBContext from Entity Framework, again, using a IDBContextFactory:
IDbDataContextFactory
public interface IDbDataContextFactory
{
myADOEntities CreateNew();
}
DbDataContextFactory
public class DbDataContextFactory : IDbDataContextFactory
{
public myADOEntities CreateNew()
{
return new myADOEntities ();
}
}
ADOModule
public class ADOModule : NinjectModule
{
public override void Load()
{
Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
}
}
Now in the DomainBL implementation I faced the problem of injecting the necessary interface for the DBContext Object Factory:
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
**** OPS, i tried to understand about 10+ Stackoverflow articles ***
...
}
What have I tried?
To Use the constructor Injection. But I don't know what to inject in the call for the Factory CreateNew() in the IDBContextFactory. For clear:
public class DomainBLFactory: IDomainBLFactory
{
// Here the constructor requires one argument for passing the factory impl.
public DomainBL CreateNew()
{
return new DomainBL(?????) // I need a IDBContextFactory impl to resolve.
//It's not like in the MVC Controller where injection takes place internally
//for the controller constructor. I'm outside a controller
}
}
In this Useful Post, our unique true friend Remo Gloor describes in a comment a possible solution for me, citing: "Create an interface that has a CreateSomething method that takes everything you need to create the instance and have it return the instance. Then in your configuration you implement this interface and add an IResolutionRoot to its constructor and use this instace to Get the required object."
Questions: How do I implement this in a proper way using Ninject.MVC3 and my modest Domain Class approach? How do I Resolve the IResolutionRoot without be punished for relaying in the Service Locator anti-pattern?
To Use the property injection for an IDBContexFactory. In the course of learning and reading all the contradictory points of view plus the theoretical explanations about it, I can deduce it's not a proper way of doing the injection for my DBContexFactory class code. Nevermind. It doesn't work anyway.
public class DomainBL
{
[Inject]
public IDbDataContextFactory contextFactory
{
get;
set;
}
//Doesn't works, contextFactory is null with or without parameterless constructor
.... (methods that uses contextFactory.CreateNew()....
}
Question: What am I missing? Even if this approach is wrong the property is not injecting.
Be cursed. Use a DependencyResolver and live with the stigmata. This works and I will remain in this approach until a proper solution appears for me. And this is really frustrating because the lack of knowledge in my last 10 days effort trying to understand and do things right.
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
this.contextFactory = DependencyResolver.Current.GetService<IDbDataContextFactory>();
//So sweet, it works.. but i'm a sinner.
}
Question: Is there a big mistake in my understanding of the Factory Approach for the injection of interfaced implementations and using a Domain Driven Approach for taking apart the Business Logic? In the case I'm wrong, what stack of patterns should I implement with confidence?
I saw before a really big quantity of articles and blogs that does not ask this important question in a open a clear way.
Remo Gloor introduces the Ninject.Extensions.Factory for the Ninject 3.0.0 RC in www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction.
Question: Will this extension work coupled with Ninject.MVC3 for general porpouse?. In such case it should be my hope for the near future.
Thank you all in advance for your guidance and remember we appreciate your kind help. I think a lot of people will find this scenario useful too.
I don't really get the purpose of your factories. Normally, you have exactly one ObjectContext instance for one request. This means you don't need the factory and can simply bind myADOEntities in Request scope and inject it into your DomainBL without adding the factories:
Bind<myADOEntities>().ToSelf().InRequestScope();
Bind<DomainBL>().ToSelf().InRequestScope();
And Yes the factory and mvc extrensions work together.
Here's an implementation of a generic IFactory to solve the problem without resorting to the ServiceLocator anti-pattern.
First you define a nice generic factory interface
public interface IFactory<T>
{
T CreateNew();
}
And define the implementation which uses ninject kernel to create the objects requested
class NinjectFactory<T> : IFactory<T>
{
private IKernel Kernel;
public NinjectFactory( IKernel Kernel )
{
this.Kernel = Kernel;
}
public T CreateNew()
{
return Kernel.Get<T>();
}
}
Binding to your factory using the following
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<myADOEntities>().ToSelf();
kernel.Bind<DomainBL>().ToSelf();
kernel.Bind(typeof(IFactory<>)).To(typeof(NinjectFactory<>));
}
You can now do the following in your controller.
public class MyController : Controller
{
private readonly IFactory<DomainBL> DomainBLFactory;
public MyController( IFactory<DomainBL> DomainBLFactory )
{
this.DomainBLFactory = DomainBLFactory;
}
// ... (use the Domain for performing tasks/commands with the Database Context)
}
And in your DomainBL
public class DomainBL
{
IFactory<myADOEntities> EntitiesFactory;
public DomainBL( IFactory<myADOEntities> EntitiesFactory )
{
this.EntitiesFactory = EntitiesFactory;
}
// ... (use the Entities factory whenever you need to create a Domain Context)
}
I have a command class that needs to have 2 constructors. However,
using structuremap it seems that I can only specify one constructor to
be used. I have solved the problem for now by subtyping the specific
command class, which each implementation implementing it's own
interface and constructor. Like the code below shows. The
ISelectCommand implements two separate interfaces for the
string constructor and the int constructor, just for the sake of
registering the two subtypes using structuremap.
However, I consider this a hack and I just wonder why is it not
possible for structuremap to resolve the constructor signature by the
type passed in as parameter for the constructor? Then I could register
the SelectProductCommand as an ISelectCommand and
instantiate it like:
ObjectFactury.With(10).Use>();
orObjectFactury.With("testproduct").Use>();
public class SelectProductCommand : ISelectCommand<IProduct>,
ICommand, IExecutable
{
private readonly Func<Product, Boolean> _selector;
private IEnumerable<IProduct> _resultList;
public SelectProductCommand(Func<Product, Boolean> selector)
{
_selector = selector;
}
public IEnumerable<IProduct> Result
{
get { return _resultList; }
}
public void Execute(GenFormDataContext context)
{
_resultList = GetProductRepository().Fetch(context,
_selector);
}
private Repository<IProduct, Product> GetProductRepository()
{
return ObjectFactory.GetInstance<Repository<IProduct,
Product>>();
}
}
public class SelectProductIntCommand: SelectProductCommand
{
public SelectProductIntCommand(Int32 id): base(x =>
x.ProductId == id) {}
}
public class SelectProductStringCommand: SelectProductCommand
{
public SelectProductStringCommand(String name): base(x =>
x.ProductName.Contains(name)) {}
}
P.s. I know how to tell structuremap what constructor map to use, but my again my question is if there is a way to have structuremap select the right constructor based on the parameter passed to the constructor (i.e. using regular method overloading).
The short answer is this post by the creator of Structuremap.
The long answer is regarding the structure you have in that piece of code. In my view, a command is by definition a "class" that does something to an "entity", i.e it modifies the class somehow. Think CreateNewProductCommand.
Here you are using commands for querying, if I'm not mistaken. You also have a bit of a separation of concern issue floating around here. The command posted defines what to do and how to do it, which is to much and you get that kind of Service location you're using in
private Repository<IProduct, Product> GetProductRepository()
{
return ObjectFactory.GetInstance<Repository<IProduct, Product>>();
}
The way I'd structure commands is to use CreateProductCommand as a data contract, i.e it only contains data such as product information.
Then you have a CreateProductCommandHandler which implements IHandles<CreateProductCommand> with a single method Handle or Execute. That way you get better separation of concern and testability.
As for the querying part, just use your repositores directly in your controller/presenter, alternatively use the Query Object pattern
I think I solved the problem using a small utility class. This class gets the concrete type from ObjectFactory and uses this type to construct the instance according to the parameters past into the factory method. Now on the 'client' side I use ObjectFactory to create an instance of CommandFactory. The implementation of CommandFactory is in another solution and thus the 'client solution' remains independent of the 'server' solution.
public class CommandFactory
{
public ICommand Create<T>()
{
return Create<T>(new object[] {});
}
public ICommand Create<T>(object arg1)
{
return Create<T>(new[] {arg1});
}
public ICommand Create<T>(object arg1, object arg2)
{
return Create<T>(new[] {arg1, arg2});
}
public ICommand Create<T>(object arg1, object arg2, object arg3)
{
return Create<T>(new[] {arg1, arg2, arg3});
}
public ICommand Create<T>(object[] arguments)
{
return (ICommand)Activator.CreateInstance(GetRegisteredType<T>(), arguments);
}
public static Type GetRegisteredType<T>()
{
return ObjectFactory.Model.DefaultTypeFor(typeof (T));
}
}
I'm trying to do some attribute-based interception using structuremap but I'm struggling to tie up the last loose ends.
I have a custom Registry that scans my assemblies and in this Registry I have defined the following ITypeInterceptor whose purpose it is to match types decorated with the given attribute and then apply the interceptor if matched. The class is defined as such:
public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor>
: TypeInterceptor
where TAttribute : Attribute
where TInterceptor : IInterceptor
{
private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator();
public object Process(object target, IContext context)
{
return m_proxyGeneration.CreateInterfaceProxyWithTarget(target, ObjectFactory.GetInstance<TInterceptor>());
}
public bool MatchesType(Type type)
{
return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0;
}
}
//Usage
[Transactional]
public class OrderProcessor : IOrderProcessor{
}
...
public class MyRegistry : Registry{
public MyRegistry()
{
RegisterInterceptor(
new AttributeMatchTypeInterceptor<TransactionalAttribute, TransactionInterceptor>());
...
}
}
I'm using DynamicProxy from the Castle.Core to create the interceptors, but my problem is that the object returned from the CreateInterfaceProxyWithTarget(...) call does not implement the interface that triggered the creation of the target instance in structuremap (i.e IOrderProcessor in example above). I was hoping that the IContext parameter would reveal this interface, but I can only seem to get a hold of the concrete type (i.e. OrderProcessor in example above).
I'm looking for guidance on how to have this scenario work, either by calling the ProxyGenerator to return an instance that implements all interfaces as the target instance, by obtaining the requested interface from structuremap or through some other mechanism.
I actually got something working with a slight caveat so I'll just post this as the answer. The trick was to obtain the interface and pass that into the CreateInterfaceProxyWithTarget. My only problem was that I could not find a way to query the IContext about which interface it was currently resolving so I ended up just looking up the first interface on the target which worked for me. See code below
public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor> :
TypeInterceptor
where TAttribute : Attribute
where TInterceptor : IInterceptor
{
private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator();
public object Process(object target, IContext context)
{
//NOTE: can't query IContext for actual interface
Type interfaceType = target.GetType().GetInterfaces().First();
return m_proxyGeneration.CreateInterfaceProxyWithTarget(
interfaceType,
target,
ObjectFactory.GetInstance<TInterceptor>());
}
public bool MatchesType(Type type)
{
return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0;
}
}
Hope this helps someone
Having seen how NInject can do it and AutoFac can do it I'm trying to figure out how to inject dependencies into MVC ActionFilters using Castle Windsor
At the moment I'm using an ugly static IoC helper class to resolve dependencies from the constructor code like this:
public class MyFilterAttribute : ActionFilterAttribute
{
private readonly IUserRepository _userRepository;
public MyFilterAttribute() : this(IoC.Resolve<IUserRepository>()) { }
public MyFilterAttribute(IUserRepository userRepository)
{
_userRepository = userRepository;
}
}
I'd love to remove that static antipattern IoC thing from my filters.
Any hints to as how I would go about doing that with Castle Windsor?
And no, changing DI framework is not an option.
When I needed this, I built upon the work others have done with Ninject and Windsor to get property injection dependencies on my ActionFilters.
Make a generic attribute: MyFilterAttribute with ctor taking a Type as argument - i.e. something like this:
public class MyFilterAttribute : ActionFilterAttribute {
public MyFilterAttribute(Type serviceType) {
this.serviceType = serviceType;
}
public override void OnActionExecuting(FilterExecutingContext c) {
Container.Resolve<IFilterService>(serviceType).OnActionExecuting(c);
// alternatively swap c with some context defined by you
}
// (...) action executed implemented analogously
public Type ServiceType { get { return serviceType; } }
public IWindsorContainer Container { set; get; }
}
Then use the same approach as the two articles you are referring to, in order to take control of how actions are invoked, and do a manual injection of your WindsorContainer into the attribute.
Usage:
[MyFilter(typeof(IMyFilterService))]
Your actual filter will then be in a class implementing IMyFilterService which in turn should implement IFilterService which could look something like this:
public interface IFilterService {
void ActionExecuting(ActionExecutingContext c);
void ActionExecuted(ActionExecutedContext c);
}
This way your filter will not even be tied to ASP.NET MVC, and your attribute is merely a piece of metadata - the way it is actually supposed to be! :-)