I am using Nancy with Ninject as IoC. All is fine. I now need to add FluentValidation.
How do I go about wiring Nancy to use FluentValidation via Ninject?
I see there's a NuGet package Ninject.Fluent.Validation but I can't find any documentation or example on how to use it.
The demo project on NancyFx website uses the TinyIoC so it's not useful to me.
UPDATE: this is what I have tried to do:
var createRequest = this.BindAndValidate<CreateRequest>();
if (!ModelValidationResult.IsValid)
{
return Response.AsJson(ModelValidationResult, HttpStatusCode.BadRequest);
}
The model is always valid (even if there should be errors reported by the CreateConsumerRequestValidator).
This is what I have added in my Ninject bootstrapper:
Bind<IModelValidatorFactory>().To<FluentValidationValidatorFactory>().InSingletonScope();
AssemblyScanner.FindValidatorsInAssemblyContaining<CreateRequestValidator>()
.ForEach(match => Bind(match.InterfaceType).To(match.ValidatorType));
The IModelValidatorFactory is wired up automatically by Nancy from v0.12 (see here Configure NancyFx with Fluent Validation) - you just need to wire up your validators.
This works with Nancy 0.23
using FluentValidation;
using Ninject.Extensions.Conventions;
using Ninject.Modules;
public class ValidatorModule : NinjectModule
{
public override void Load()
{
this.Kernel.Bind(
x =>
x.FromAssembliesMatching("YourNameSpace.*")
.SelectAllClasses()
.InheritedFrom<IValidator>()
.BindAllInterfaces());
}
}
Related
Is there any way to register a "catch all" to the .net core dependency injection? That uses any dependencies it has and makes a instance? I know this worked in old framework apps (using StructureMap) and cant find a way to do it in .net core (without using a extra NuGet package). As a very simple example trying to get UnkownClass throws a exception
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace DICatchAllTest
{
class Program
{
static void Main(string[] args)
{
var services = new ServiceCollection().AddLogging()
.AddSingleton<KnownClass>();
var serviceProvider = services.BuildServiceProvider();
serviceProvider.GetRequiredService<UnknownClass>();
}
}
public class KnownClass
{
public KnownClass(ILogger<KnownClass> logger, UnknownClass unknownClass)
{
//Set these to properties to be used late
}
}
public class UnknownClass
{
public UnknownClass(ILogger<UnknownClass> logger)
{
//Set these to properties to be used late
}
}
}
I suppose with "catch all" you mean you'd like the DI-container to find the required types itself without you having to register them. That's indeed a feature that some DI-frameworks have but the .net one does not. However, there are many libraries that allow you to accomplish this. For example Scrutor. Here is an example of how to use it.
As #Steven explained it is not something that is supported by the out of the box .net core DI container. So I will look into a third party container for this functionality.
I'm using "FluentValidation.AspNetCore" library (Version="8.6.2") for a .Net Core project.
What I would like to do is to register all my Validators automatically in Startup.cs class, using something like this (which is what I'm using now):
services.AddControllers().AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<Startup>());
But the problem is that my validators are going to be moved to another assembly (required by client), so I can't use Startup as reference for the registration.
Is there a way I can do this without having to register the validators one by one?
For registering Validator, there are three ways.
Registering each validator in Service with AddTransient.
Registering using “RegisterValidatorsFromAssemblyContaining” method registers all
validators derived from AbstractValidator class within the assembly
containing the specified type.
Registering using “RegisterValidatorsFromAssembly” method.
source here
If you use option number 2 and replace Startup in your code with any class derived from AbstractValidator from another assembly, it will register all validators from that assembly
Example:
services.AddControllers().AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<AnotherValidationClass>());
You can use the official nuget package for that:
services.AddValidatorsFromAssemblyContaining<SomeValidator>();
or
services.AddValidatorsFromAssemblyContaining(typeof(SomeValidator));
or
services.AddValidatorsFromAssembly(typeof(SomeValidator).Assembly);
All possible DI options described here
AddFluentValidation() is deprecated.
source : https://github.com/FluentValidation/FluentValidation/issues/1965
old:
builder.Services.AddControllersWithViews().AddFluentValidation(fv => { });//or AddMvc(), AddMvcCore()
//or
builder.Services.AddFluentValidation(config =>
{
config.ConfigureClientsideValidation(enabled: false);
});
new :
builder.Services.AddValidatorsFromAssemblyContaining<AnyValidator>() // register validators
builder.Services.AddFluentValidationAutoValidation(); // the same old MVC pipeline behavior
builder.Services.AddFluentValidationClientsideAdapters(); // for client side
Having soured books, I can't figure out what in a C# MVC project I'm taking over causes the Controller constructors to always be passed a repository argument.
public partial class AdminController : ApiController
{
IDataRepository _repo;
public AdminController(IDataRepository repo)
{
_repo = repo;
}
}
Even other classes who are NOT partials are written this way.
I have looked at the class (or Interface) that these inherit from.
Any ideas?
Thanks in advance.
This is called dependency injection.
Asp.net core has a built-in DI container. But for old Asp.net projects, you should add a library to use this. I don't know which library you use, but I can give some common examples:
Simple Injector
https://simpleinjector.readthedocs.io/en/latest/aspnetintegration.html
// You'll need to include the following namespaces
using System.Web.Mvc;
using SimpleInjector;
using SimpleInjector.Integration.Web;
using SimpleInjector.Integration.Web.Mvc;
// This is the Application_Start event from the Global.asax file.
protected void Application_Start(object sender, EventArgs e) {
// Create the container as usual.
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
// Register your types, for instance:
container.Register<IUserRepository, SqlUserRepository>(Lifestyle.Scoped);
// This is an extension method from the integration package.
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
Castle Windsor
https://gist.github.com/martinnormark/3128275
public class ControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly()
.Pick().If(t => t.Name.EndsWith("Controller"))
.Configure(configurer => configurer.Named(configurer.Implementation.Name))
.LifestylePerWebRequest());
}
}
Asp.net Core
https://learn.microsoft.com/tr-tr/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<IMyDependency, MyDependency>();
}
Like others have said, dependency injection. But some more details:
.net framework and .net core handle it differently.
It's not built in at all in the .net framework. You'll want to check you global.asax file to figure out whats going on. Most of the time its done through a nuget package. there are many popular ones like autofaq, ninject, simple injector etc. You should see some stuff about building a container and registering services.
.net core has its own dependency injection framework it ships with, so quite often that's used. Although sometimes people still use a nuget package for something more complex. The .net core stuff will be in the Startup.cs file. See if theres anything like services.AddTransient anywhere.
It's possible, though unlikely someone wrote there own dependency injection framework in your project. In that case you'd be looking for them to have written a ControllerFactory implementation.
If you can't figure it out from here, please add either the global.asax file, or the startup.cs file to your question.
This is Dependency Injection, have a look in startup for something like
services.AddTransiant<IDataRepository, DataRepo>();
This tells the dependency injection container to instantiate IDataRepository with an instance of DataRepo.
I just started using LightInject for my MVC project and it's working just fine.
But i wanted to use it for my SignalR hubs too. So i followed the instructions at http://www.lightinject.net/#signalr. However i cannot see the method ServiceContainer.RegisterHubs anywhere. I have installed the LightInject, LightInject.Mvc and LightInject.SignalR dll's.
using log4net.Config;
using LightInject;
using Microsoft.Owin;
using Owin;
using MvcProject;
using MvcProject.ApplicationServices.Interfaces.EventSignups;
[assembly: XmlConfigurator(ConfigFile = "Web.config", Watch = true)]
[assembly: OwinStartup(typeof (Startup))]
namespace MvcProject
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
//ConfigureAuth(app);
var container = new ServiceContainer();
container.Register<IEventSignupService>();
container.Register<IViewModelRetrieverEventCommentService>();
container.Register<IViewModelRetrieverEventService>();
container.RegisterHubs(); //cannot see method
app.MapSignalR(container.EnableSignalR());
}
}
}
Anyone knows what i'm doing wrong?
Unfortunately this is just bad documentation. The method does not exist and never existed. You have to register each and every hub manually within your LightInject Container.
Also, be aware of issues I've encountered by changing the DependencyResolver within SignalR for LightInject.
PS: I know my answer is late but still tought it could be useful for people searching for the same issue.
I'm new with using structuremap and I'm not sure if I configured IoC.cs properly.
I have an ASP.Net Project and used Unit Of Work. this is how my IoC.cs file looks like:
IoC.cs
namespace Portal.Web.DependencyResolution {
using Portal.Data.Context;
using Portal.Service;
using Portal.Service.Interface;
using StructureMap;
using StructureMap.Pipeline;
public static class IoC {
public static IContainer Initialize() {
return new Container(c => {
c.AddRegistry<DefaultRegistry>();
c.For<IUnitOfWork>().LifecycleIs(Lifecycles.Singleton).Use<PortalDbContext>();
c.For<IAccount>().Use<AccountService>();
c.For<IStandard>().Use<StandardService>();
});
}
}
}
with this configuration this error occures some times
System.Data.SqlClient.SqlException: New transaction is not allowed because there are other threads running in the session.
I already have read many other SO questions with same topic as error above and they all suggest to use .toList() and enumerate but I guess that is not my problem.
so for summarize I'd like to use Unit Of Work + Structure Map 3 DI in ASP MVC5, how I configure my IoC.cs
It is very bad idea to use singleton for dbcontext in web application.
You should consider to change this to PerHttpRequest lifecycle (if it exists in structuremap) or PerResolve lifecycle:
Per HttpRequest:
For<IUnitOfWork>().LifecycleIs(new HttpContextLifecycle()).Use<PortalDbContext>();
Update:
in this case, you should not use your IUnitOfWork in using statement and lay responsibility of disposing it on your DI container.
Per Resolve:
For<IUnitOfWork>().Use<PortalDbContext>();