I am new to Simple Injector.
I have a WCF service with a class Testservice implementing a interface ITestService. As per the Simple Injector documentation, in the svc markup I have added the factory attribute as "SimpleInjector.Integration.Wcf.SimpleInjectorServiceHostFactory, SimpleInjector.Integration.Wcf". Also in the AppStart , I have registered the container using the following
container.RegisterWcfServices(Assembly.GetExecutingAssembly()); &
container.Register<ITestService, TestService>(Lifestyle.Scoped);
The WCF works fine. Now I need to consume the service TestService from my MVC app.
In my MVC App, I have added the SimpleInjector.Integration.Web and SimpleInjector.Integration.Web.MVC through Nuget and also added the WCF service reference.
I am struck on registering the TestService class in App Start of my MVC application in order to inject in my controller. The container needs to be registered as
container.Register(ITestService, <TImplementation>);
but I am unable to resolve or find out what I need to give on the TImplementation. It requires a Implementation class which is the TestService but the TestService is available in WCF componebt and only I have the interface reference here in my MVC app.
Can somebody guide whether my approach is right and the solution for above. Thanks in Advance.
You can provide a factory method to SimpleInjector in the register method that it will use to build your object.
container.Register<ITestService, TestService>(Lifestyle.Scoped);
Can be written as
container.Register<ITestService>(() => new TestServiceClient(), Lifestyle.Scoped);
You are then free to choose the constructor you want to use in the factory method
Related
I have 4 Projects in a solution
DAL_Project
BLL_Project
Interface_Project
WebApi_Project
Interface_Project has two interfaces ICar_DAL and ICar_BLL
DAL_Project has a class Car_DAL that implements ICar_DAL
BLL_Project has a class Car_BLL that implements ICar_BLL and its constructor takes in ICar_DAL
WebApi_Project has an api controller CarApiController and its constructor takes in ICar_BLL
the dependency resolution of WebApi Controller's constructor is done by Unity.WebApi using this in Bootstrapper.cs:
container.RegisterType<ICar_BLL, Car_BLL>();
this would have worked if my Car_BLL further didn't require ICar_DAL in its constructor.
to make it work i can do some thing like this:
container.RegisterType<ICar_BLL, Car_BLL>();
container.RegisterType<ICar_DAL, Car_DAL>();
but that would mean that i need to add reference to DAL_Project in my WebApi_Project which is something i would never want to do. DAL_Project should only be referred by BLL_Project
How can i solve this issue?
but that would mean that i need to add reference to DAL_Project in my
WebApi_Project which is something i would never want to do.
Oh you seem to have some misunderstanding about how Dependency should be done if you don't want to do that. The DI container is configured in the outermost layer of your application which is actually the host. It is also referred to as the Composition Root. In your case this is the hosting application of your Web API. If you are using ASP.NET to host your Web API then this is the right place to do the composition root and reference all the other underlying projects.
Personally in complex project I tend to have a ProjectName.Composition class library which serves me as a Composition root. this is where I configure my DI container and this is the project that references all the others - coz obviously in order to configure your DI root you need all the dependent projects and implementations. This .Composition assembly is then references in the hosting application and the Bootstrapper.Initialize method called in the Initialize method of the hosting application.
In the case of ASP.NET host that would be Application_Start in Global.asax
In case of a desktop application or a self-host that would be the Main method which is the entry point.
I have a piece of code that encapsulates functionality that isn't specific to Orchard. However i need to make it available in Orchard via dependency injection. So, I built up an Autofac Module that registers all components (types), but I can't find a way to inform Orchard's Autofac Container about it.
From what i red, there are two ways to add a module to a container:
By supplying the module at to the ContainerBuilder (usually at start-up),
Or by updating the already built Container at runtime with a ContainerBuilder
I can approach the problem in the first way, but I rather do a variant of the second if there is such?
Just add a class deriving from Autofac.Module to your Orchard module and that's it. It will get automatically picked by Orchard during the container construction.
Piotr Szmyd's answer is fundamentally correct, but here's some more detail:
Your Orchard Module is the new .csproj that you've added to the Orchard.sln
Add Autofac as a reference to that csproj (make sure you use the version included with Orchard - not nuget. See here for more details about that problem)
Then add a class that derives from Autofac.Module and which implements Load(ContainerBuilder).
e.g.
using System;
using Autofac;
namespace MyCustom.Module.Namespace
{
public class LoaderModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyClass>().As<IMyInterface>();
}
}
}
As an additional note:
The Autofac registration code only gets invoked at application startup time.
If you are running with the site sitting locally in IIS and the code in VS, then the dynamic compilation nature of Orcahrd means that when you recompile the code, the application doesn't stop.
So in order for this Autofac registration code to be hit (and also for any channges to it to take effect) you have to iisreset to kill the application, so that it reloads the Autofac Registrations.
We are hitting the following error in some of our environments, seemingly after the app pool recycles.
An instance of IControllerFactory was found in the
resolver as well as a custom registered provider in
ControllerBuilder.GetControllerFactory. Please set only one or the other.
We are not using the ControllerBuilder to register our controller factory, only the IDependencyResolver as pointed out in the this blog
We are using Castle Windsor (seemingly unrelated), as our container, and in the Application_Start of the Global.asax, first registering all of our dependencies and calling the following to register the IDepencencyResolver.
DependencyResolver.SetResolver(new WindsorDependencyResolver(IoC));
What could be causing this exception? Any help would be appreciated.
Using the MVC DependencyResolver with Castle Windsor is not recommended as it has a design flaw: it does not release service instances when it should. See this article for a full explanation.
Instead, use the method illustrated in the Windsor documentation which uses a custom factory to inject dependencies into controllers.
For information, I had the same error message (with ninject). I don't understand why because the application started well in other machine. I tried to clear caches... but error was still present. I had redo a checkout in my repository and it was OK...
While developing web project using ASP.NET MVC, I came up against a coupling problem.
When I build custom controller factory (or dependency resolver if using MVC 3), I need this factory to know somehow where to get dependencies from. Here's my code:
//from Global.asax.cs
DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
Container repositories;
public StructureMapControllerFactory()
{
repositories = new RepositoriesContainer();
}
//... rest of the implementation
}
class RepositoriesContainer: Container
{
public RepositoriesContainer()
{
For<IAccountRepository>().Use<SqlAccountRepository>();
//...
}
}
StructureMapControllerFactory class is responsible for injecting dependencies into a controller. As I said, it needs to know where to find these dependencies (I mean concrete classes, like services and repositories implementations).
I have a separate class library called MySite.Data, where all the implementation details live. Contracts, like IAccountRepository, live in library MySite.Contracts. Now, if I reference this MySite.Data library directly from MVC project, there will be a dependency between my site and implementation of its data retrieval. The question is how can I remove it? What are best practices in this situation?
I'm sure it does have a bunch of workarounds, just I haven't found any yet.
Well, as I see it, you can't do exactly that. Your MVC project really really needs to know about concrete classes it is going to use.
You will anyway have to provide those container registrations somewhere and you'll get the dependency on the project/assembly where that type is defined. Shortly, you have to reference MySite.Data from MVC project. Like that:
MySite.Data knows nothing about MVC project
MVC project knows the concrete repositories types to provide correct container registrations.
You can make life simpler with StructureMap Registry objects but you need to include those Registries somewhere as well. Typically those are in the main project or some "StructureMap-adapter" project but you'd need to make reference anyway.
I'd advise that you:
Use MVC3 and drop your custom IControllerFactory if you only use it for DI into your Controllers.
Use StructureMap Registry objects to provide each and every IoC registration ever needed.
Use StructureMap Assembly scanning capabilities to provide components discovery.
Use something much more common as a DependencyResolver, i.e. not a StructureMapControllerFactory but a CommonServiceLocator with StructureMap adapter instead.
Try to abstract from StructureMap itself inside your main app.
And, of course, don't be afraid of making references inside the main project - they have nothing about coupling. It doesn't decrease maintainability. But the wrong architecture does, so be worried about that, not simple reference.
I have a custom membership provider which works fine until I use unity in the web application.
public class CustomMemberProvider : MembershipProvider
I have done some googling and found the snippet below to place in the application_start() of the global file but I am not sure what I need to do to it to make it work for my custom provider. Basically when I make a call on validateUser() on my security controller it fails to resolve the dependencies.
_container.RegisterType<IFormsAuthenticationService, FormsAuthenticationService>()
.RegisterType<IMembershipService, AccountMembershipService>()
.RegisterInstance<MembershipProvider>(Membership.Provider);
I thought I could swap "AccountMembershipService" for "CustomMemberProvider" but that causes the Controller Type to be null in the standard "UnityControllerFactory".
Has anyone had the same problems?
thanks.
AccountMembershipService is probably the same service that VS generates. This service implements IMembershipService (a custom interface generated by the code). Simply swapping out AccountMembershipService for CustomMemberProvider is not going to be the same thing.
Essentially, your custom membership provider implements the abstract class "MembershipProvider" which is different than this "AccountMembershipService" which is a wrapper to SqlMembershipProvider.
You need to make a wrapper to your membership provider to implement a type. Also, I'm pretty sure Membership.Provider is going to take you to System.Web.Security.MembershipProvider and not your custom provider.