Use Ninject in both main and referenced projects - wcf

I have MVC4 website project and WCF project, both using Ninject.
I want to use class from WCF project in website project. I add reference to project and get both NinjectWebCommon.Start() executing (with "The static container already has a kernel associated with it!" error).
Is there way to make what I want?

Solved this using this startup in referenced project
public class Global : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
return new StandardKernel(new ServiceModule());
}
}

Related

Read Config From Another Project - Log4Net ASP.NET Core 3.1

I am trying to write a class library that uses log4net that looks something like this:
public class Logging
{
private ILog log4netLogger = null;
public Logging(Type type)
{
XmlDocument log4netConfig = new XmlDocument();
log4netConfig.Load(File.OpenRead("log4net.config"));
var repo = LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
XmlConfigurator.Configure(repo, log4netConfig["log4net"]);
log4netLogger = LogManager.GetLogger(type);
}
public void Debug(string message)
{
log4netLogger(message);
}
public void Info(string message)
{
log4netLogger(message);
}
}
However, the xml configuration is in my test console app in C:\....\TestLogging\TestLog4Net\bin\Debug\netcoreapp3.1. I actually started with this console app to test log4net but I have moved all my code from the main method of Program.cs to the Logging.cs constructor, but I think the LogManager will not be able to find this now.
Is this at all possible?
I think it is possible. To use the log4net in the class library, you have to install the log4net package in the class library, then, you could add the class library reference in the console application and use the class library method. But, as you said, the log4net.config file should be in the console application netcoreapp3.1 folder, otherwise, the class library will not find the log4net.config file:

Using ninject dependecyResolver for both MVC and WebAPI

I have created and MVC 4 web application and decided to use web api in this app.
I'm using ninject dependency resolver for MVC web app. and now I want to use this ninject dependency resolver for web api.
but the problem raise here mvc IDependencyResolver namespace is: using System.Web.Mvc
and web api IDependencyResolver is using System.Web.Http.Dependencies
so how can I solve this issue?
finally I want something like this:
// Use the container and the NinjectDependencyResolver as
// application's resolver
var resolver = new NinjectDependencyResolver(container);
//Register Resolver for MVC
DependencyResolver.SetResolver(resolver);
//Register Resolver for Web Api
GlobalConfiguration.Configuration.DependencyResolver = resolver;
There is a way to share same container between MVC and ASP.NET Web API.
You just need to implement both interfaces.
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
private readonly IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(this.kernel.BeginBlock());
}
}
Check this article for solution:
Simple Way to share Dependency Resolvers between MVC and Web API
There is a NuGet package that does this. Add the NInject, NInject.Web.Common, NInject.MVCx and WebApiContrib.IoC.Ninject NuGet packages to your project. A NInjectWebCommon class should have been created in the App_Start folder. Add your binding for your dependencies to the RegisterServices method. In the CreateKernel method after the RegisterServices(kernel) call, add the following line:
GlobalConfiguration.Configuration.DependencyResolver = new NinjectResolver(kernel);
This will let you create the Ninject dependency resolver without having to create your own override class. Easy, right?

How to resolve dependency inside AuthorizeAttribute with WebApi and Ninject

My current setup is using Ninject for simple IoC, everything goes fine, but I'm not able to resolve one of the classes I need inside my AuthorizeAttribute. I need to access a class that does ClaimsVerification:
Here's my code:
IoC Config:
var kernel = new StandardKernel(); // Ninject IoC
// These registrations are "per instance request".
// See http://blog.bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/
kernel.Bind<RepositoryFactories>().To<RepositoryFactories>()
.InSingletonScope();
kernel.Bind<IRepositoryProvider>().To<RepositoryProvider>();
kernel.Bind<ISmartDocumentorUow>().To<SmartDocumentorUow>();
kernel.Bind<IClaimsVerification>().To<ClaimsVerification>();
// kernel
//kernel.BindFilter<MyAuthorizeAttribute>(FilterScope.Controller, 0).WhenControllerHas<RequireRolesAttribute>();
// Tell WebApi how to use our Ninject IoC
config.DependencyResolver = new NinjectDependencyResolver(kernel);
MyAuthorizeAttribute:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
[Inject]
IClaimsVerification clamisverify { get; set; }
public MyAuthorizeAttribute()
{
//var x = System.Web.Mvc.DependencyResolver.Current.(typeof(IClaimsVerification));
}
Yap, sorry, the problem was injecting the iClaimsverification that isn't working in web api..
I tryed with the public property and still it didn't work.
the bindfilter is commented out, because it doesn't exist in the core NInject api (dll), it does exists in the MVC dll of ninject but it works for Action filters in the web mvc, and not in the api mvc for what i can tell..
i do solved the issue like this, though i don't like a lot of this fix:
private IClaimsVerification verifier
{
get
{
return (GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IClaimsVerification)) as IClaimsVerification);
}
}
The property you have marked with Inject is private - you need to initialize Ninject with a custom configuration to opt into what would be a much less efficient process
(You didnt state the problem in your question. I see you were trying BindFilter, but it's commented out (why?) - this is the correct approach. I recommend reading the Ninject.MVC3 wiki article on BindFilter for an example)

Upgrading Ninject/Ninject WCF Extensions to the latest version 3.0.0.5

I am currently using Ninject (2.2.1.4) and Ninject.Extensions.Wcf (2.2.0.4) with my WCF service. I would like to upgrade to Ninject (3.0.0.15) and Ninject.Extensions.Wcf (3.0.0.5) and it doesn't look like I can use my current approach anymore. Can anyone point me to some samples or posts on how to get the latest version of Ninject working with a WCF project.
My current approach:
I wrote a module:
public class NinjectDependencyResolver : NinjectModule
{
public override void Load()
{
// Declare bindings
}
}
I added the Factory Attribute to my .svc file
Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory"
I added a Global.asax to the WCF project
public class Global : NinjectWcfApplication
{
protected override IKernel CreateKernel()
{
return new StandardKernel(new NinjectDependencyResolver());
}
}
Now I can modify the default constructor in my service and use constructor injection.
Any pointers on how I could upgrade are appreciated.
Thanks
Add Ninject.Web.Common and derive from NinjectHttpApplication or use the App_Start file that comes with the NuGet package.

How to share fluent configuration in a Castle Windsor IOC container

I am trying to create an IOC container in Castle Windsor that's configuration is shared across assemblies.
(What follows is an example of how this works in Unity. What I want to do is to make it work the same way using Castle Windsor)
I have the following project configuration...
TestCompany.Services.Host
(Web project hosting a number of .svc files)
PrintService.svc
Web.Config
Unity.Config
TestCompany.Services.PrintService
IPrintService.cs
PrintService.cs
The actual implementation of my "PrintService" is not implemented inside my Services.Host but in the TestCompany.Services.PrintService assembly.
As part of my shared project code (not shown) I have a container helper which is responsible for loading the unity configuration...
public static IUnityContainer GetContainer()
{
// Checks for existance of container (_container == null) ommitted.
var section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
section.Configure(_container, name);
...
...
}
This method loads the unity configuration section from the Unity.Config and uses it to configure the container.
The advantage of this method is that one Unity.Config loaded inside (I presume) the AppDomain can service a number of assemblies. Simply calling GetContainer() from any of the assemblies consumed by my service host will return a container populated with the same type resolution's etc.
I really want to use the fluent configuration in Castle Windsor but I dont see how without this "shared" configuration file that can be acheived. PrintService and any future services will all need to resolve the same dependencies and I dont want to have to repeat my fluent configuration between these services.
Ideally I need some sort of container configured in the service host app that can "flow" into all of the assemblies that it makes use of.
Thanks.
I think I may not be understanding your question but I think I understand your scenario and here is how I do something similar, if it helps at all...
My Philosophy:
Each part of the application should be in charge of registering what
it knows about and nothing more, so there is no need for a single
central configuration file and things that are shared between
components are registered in one place and their interfaces are
available everywhere via a common library.
So let's take an example...
First of all, let us just say (for the purposes of my example) that IPrintService is something that you want to register an implementation of once and use throughout the application and that we have some other component that needs to be implemented by some external module from the main application. We, therefore, create an assembly called Common like so:
Common
public interface IPrintService
{
void Print();
}
public interface IMyService
{
void DoSomething();
}
Now let us think about the main part of the application (maybe it is an ASP .NET application, maybe justa console application, does not really matter). Here we construct the container and ask it to find all the possible components. We can do that like so:
Main Application
// Could be the Global.asax code behind but for simplicity this is
// just a console application
class Program
{
private static readonly IWindsorContainer Mycontainer
= BootstrapContainer();
// Allow access to the raw container - this is probably a bad idea but
// in the rare case that you need it you can get it from here
public static IWindsorContainer Container { get { return Mycontainer; } }
private static IWindsorContainer BootstrapContainer()
{
// Here we will just install every IWindsorInstaller found in any
// assembly in the same folder as the application (so no need for
// references or anything).
var c = new WindsorContainer();
string folder = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location);
c.Install(FromAssembly.InDirectory(new AssemblyFilter(folder)));
return c;
}
}
// Here is the print service implementation
public class MyPrintService : IPrintService
{
public void Print()
{
// Print!
}
}
// This is the installer for the main module - here we are saying exactly
// what is implementing the interface
public class MainApplicationInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container,
IConfigurationStore store)
{
container
.Register(Component
.For<IPrintService>()
.ImplementedBy<MyPrintService>());
}
}
So now we have a common library with our shared inetrfaces and a main application that will register an implementation for our shared interface and also load up any other modules in the system.
The only thing, therefore, left to do is to consume that print service and use it. We can do this anywhere that is using the container so let's create a third assembly that references only Common (we will call it test module.
Test Module
// This installer installs just the things inside this module since that
// is all it knows about but those things can use things that are
// registered in the container by anybody.
public class TestModuleInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container,
IConfigurationStore store)
{
container
.Register(Component
.For<IMyService>()
.ImplementedBy<MyServiceThatDoesSomething>());
}
}
public class MyServiceThatDoesSomething : IMyService
{
private readonly IPrintService _printService;
public MyServiceThatDoesSomething(IPrintService printService)
{
_printService = printService;
}
public void DoSomething()
{
// Use the print service!
_printService.Print();
}
}
Finally compile everything and copy the test module to the same folder as the main application and then from the main you can do this:
Container.Resolve<IMyService>().DoSomething();
And then the magic happens! Well, some code runs and you find that the print service is called by the class from the module even though it knows nothing about it.
Anyway, maybe that helps a little bit, maybe not, good luck!