I have a windsor container and windsor doesnt inject my property. The curious thing is with ServiceA the dependency is resolved but not with the component.
Container.AddFacility<WcfFacility>();
Container.Register(Component.For<PublisherService>().AsWcfService());
Container.Register(Component.For<IExecutionProgram>().ImplementedBy<ExecutionProgram>());
Container.Register(Component.For<IValidationProgram>().Instance(Factory.CreateProgramA()));
Container.Register(Component.For<RunnerService>().AsWcfService());
This is my Factory (All the Dependencies implement the same interface and all SubDependencies implement an other shared Interface):
public static class Factory{
public static IValidationProgram CreateProgramA(){
var program = new ValidationProgram(
new DependencyA(
new SubDependencyA(),
new SubDependencyB(),
),
new DependencyB()
);
}
}
In my RunnerService the IExecutionProgram, Property will be resolved.
In my IValidationProgram, I created the IExecutionProgram will not be resolved.
Properties are public in both Implementations.
What did I do wrong?
EDIT:
I added the factory. These Dependencies are all Interfaces and I need specific implementations for a program. So in general I would like to switch easily between programA or programB. I looked into type Facilities like Marwijn supposed, but I cant get the hang of it. How do I use it in my case?
Related
From what I understand, in abp, when a class implements, ITransient interface, it is automatically registered in the dependency injection system.
When I create a new project in ASPNetZero, and a class implements the ITransient, I cannot inject the said class in other projects e.g Application
Using the following snippet does not allow me to use constructor injection.
public interface ITrackAppService : ITransientDependency
public class TrackAppService : ITrackAppService
But when I register it (Even if the class does not implements ITransient), then I can use constructor injection.
IocManager.RegisterIfNot<ITrack, Track>();
Did I mistakenly understood how ITransient works?
How do I use Itransient so I can use constructor dependency injection?
Note: The class I'm trying to inject to the Application project is in a different project I created.
If you are injecting an interface to a new project, you cannot use it that way out of the box. Because your new project doesn't know your dependencies.
Each new project that uses DI must to be set as an AbpModule.
See a sample module declaration.
[DependsOn(typeof(MyBlogCoreModule))]
public class MyBlogApplicationModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
Look out the [DependsOn] attribute on the class. This helps to register the project to the DI.
So what you need to do is,
Create a new class in the new project like I showed you above.
Add the [DependsOn(typeof(YourApplicationServiceModule))] attribute to this new module.
I'm using unity to implement Dependency Injection in my .NET Web Api app.
Here is the relevent part of my WebApiCongig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
AppDependancyRegistry.Register(container);
config.DependencyResolver = new UnityResolver(container);
}
}
And here is my AppDependancyRegistry class
public static class AppDependancyRegistry
{
public static void Register(UnityContainer container)
{
container.RegisterType(typeof(IBaseRepository<>), typeof(BaseRepository<>));
//container.RegisterTypes( AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default);
}
}
I have mapped the Generic Repositores but I couldnt get through with registering the Manager classes to its interfaces. I dont want to map every one of Manager classes Manaually.
I have commented the part I have done from all the research. I just want a confirmation, this is how I do it as I cant get my App running now without doing some more of stuff
My manager classes:interfaces looks like
DutyManager: IDutyManager
UserDetailManager:IUserDetailManager
etc. Thanks in Advance
You will need, at some point, to register each of them. However, if you don't want to manually do each and every one of them, what you could "basically" do is, by reflection, load the assembly, iterate over every interface, check how many classes implement that interface, if there is only one, register the interface to that class as an unnamed registration.
Why unnamed? Well, named registration are useless unless you actually use the name in the registration, or in the ResolvedParameter constructor, and since you're not "hand crafting" the registrations, you wouldn't refer to them most likely.
Don't forget though that in your case, since the interface and the classes are generics, you'll need to check the ParameterType too.
I found the solution to this qn. Using Unity we can directly Map all classes to respecive Interfaces by using
container.RegisterTypes( AllClasses.FromLoadedAssemblies(), WithMappings.FromMatchingInterface, WithName.Default);
Here, Unity maps by convention where they map like this
DutyManager: IDutyManager
UserDetailManager:IUserDetailManager
I'm trying to register multiple implementation of single interface, but I would like to avoid using named type registration. Let's say I'm having following code:
public interface IStorage { ... }
public class DocumentStorage : IStorage { ... }
public class ImageStorage : IStorage { ... }
public interface IRepository { ... }
public class DocumentRepository : IRepository
{
public DocumentRepository(IStorage storage /*, ... and other dependencies */) { ... }
}
And doing all Unity IoC registration on single file. Rest of application does not have access to container (+ service locator pattern is big no no in my code)
Registering this would then look like this:
container.RegisterType<IStorage, DocumentStorage>("document");
container.RegisterType<IStorage, ImageStorage>("image");
container.RegisterType<IRepository, DocumentRepository>(
new InjectionFactory((c, t, s) => new DocumentRepository(
c.Resolve<IStorage>("document") /*, ... resolve other deps here */)));
And here is lying my laziness issue - I really don't want to write resolution of all dependencies this way - this makes IoC hassle. I would have to go trough all registrations depending on one of IStorage implementations and resolve all other dependencies manually.
I was thinking of turned-around solution by registering DocumentStorage resolved by DocumentRepository - which I'm not able to figure out, and moreover, it is putting dependency on another side of "equation" ("register type for being injected to another type" (instead of "register type and let it be resolved if something depends on it")).
Is there any other way how to make registration easier? (I'm not focusing on factory here - I could imagine other non-factory-able usages requiring similar way of registering dependencies)
Thanks for any advice :)
Im trying to seperate my Model,View and ViewModel in different assemblys and instantiate them with Castle Windsor.
I have my app.config
<components>
<component id="ViewModel.SomeViewModel" service="TEST.Business.IViewModel, TEST.Business" type="TEST.ViewModel.SomeViewModel, Test.ViewModel" />
<component id="ViewModel.SomeView" service="TEST.Business.IView, TEST.Business" type="TEST.View.SomeView, Test.View" />
</components>
and resolve it by
IoC.Configure();
var viewModel = IoC.Resolve<IViewModel>();
var view = IoC.Resolve<IView>();
view.ShowDialog();
my static IoC class
public static class IoC
{
private static IWindsorContainer container;
public static void Configure()
{
IResource resource = new ConfigResource("castle");
container = new WindsorContainer(new XmlInterpreter(resource));
}
public static TService Resolve<TService>()
{
return container.Resolve<TService>();
}
}
really simple until yet.
But i would love to do it like this:
naming have to be like this: I[someName]ViewModel and I[someName]View
and then resolve every component in my app.config thus for each pair of View and ViewModel resolve and associate them.
I guess there are many solutions for my problem but i dont know which keywords to use.
btw: I[someName]ViewModel and View are ofc IViewModels and IViews
I think you're doing it wrong.
Do not abstract your views and view models. It gives you no benefit. Therefore the problem is an architectural one, not a technical one.
Use reflection to iterate over the types in the assemblies you want to resolve. You can use Classes for registrations.
var assembly = Assembly.GetExecutingAssembly(); // Replace with the assembly you want to resolve for.
var exports = assembly.ExportedTypes;
var viewTypes = exports.Where(t => t.GetInterface(typeof(IView).FullName) != null);
foreach (var viewType in viewTypes)
{
var viewModelType = assembly.GetType(viewType.FullName.Replace("View", "ViewModel"));
var viewModel = container.Resolve(viewModelType);
var view = container.Resolve(viewType);
view.ShowDialog();
}
In your example, I can't see any dependency between IViewModel and IView so your code doesn't make sense. If the view model is injected as a parameter of the constructor it will be automatically resolved.
I would not recommend doing this technique. It is probably more complicated than it needs to be. Are you sure you really understand how to use an IoC container/Castle Windsor?
Ioc containers are great once you get used to them. In general you only want to use your container from your main/bootstrapping code of your application. To me it seems you try to make the resolve function for the container static to allow resolving compoents anywhere. This should not be required.
If you are looking for a method to bind views and view models in nice way, take a look at caliburn micro. You can combine this with most Ioc containers, including windsor
Kind regards,
Marwijn.
I'm designing a simple aspects framework using the DynamicProxy stuff and StructureMap and I've run up against an issue. I have the following method in my Registry:
public T AddAspectsTo<T>(T concreteObject)
{
ProxyGenerator dynamicProxy = new ProxyGenerator();
return (T)dynamicProxy.CreateInterfaceProxyWithTargetInterface(typeof(T)
,concreteObject,
new[] { (IInterceptor)new AspectInterceptor(attributeMap) });
}
Which allows me to write code like:
For<ITestClass>().Use<TestClass>().EnrichWith(AddAspectsTo<ITestClass>);
The important thing is that I'm creating a concrete version of AspectInterceptor. In that class I need to grab items from the IoC container, but at this point I don't know about the IContainer object.
I won't need access to the IoC container until the resulting ITestClasses are in use and so the IContainer will have been created, but can't figure out how to grab the instance?
To be clear, I'm talking about cases here where we setup the structuremap container with:
IContainer container = new Container(new ItemWithPropertiesRegistry());
rather than the standard ObjectFactory stuff, which works fine.
The instance to enrich is available via a lambda:
For<ITestClass>().Use<TestClass>().EnrichWith(x => AddAspectsTo<ITestClass>(x));