NRules Issue: Rule Matching on super class dont work - nrules

i have a class C, which inherits from A.
Now i want to write a Rules, that matches on type A. So I tried the following code:
public class tmp : Rule
{
public override void Define()
{
A t = null;
When().Match<A>(() => t);
Then().Do(ctx => Console.WriteLine("test"));
}
}
But this don't work. Can anyone explain, how I can fix this issue?
This doesnt work.
Best regards

Matching on the parent class definitely does work in NRules. Here is a full working example.
public class A
{ }
public class C : A
{ }
public class TestRule : Rule
{
public override void Define()
{
A fact = null;
When()
.Match(() => fact);
Then()
.Do(x => Console.WriteLine("Test"));
}
}
public class Program
{
static void Main(string[] args)
{
var repo = new RuleRepository();
repo.Load(x => x.From(xx => xx.AssemblyOf<Program>()));
var factory = repo.Compile();
var session = factory.CreateSession();
session.Insert(new C());
session.Fire();
}
}
If you post the rest of your code, I can update this answer and show where the issue is.
Maybe you didn't insert the fact into the session, or maybe you didn't call the Fire method, or maybe you didn't include the rule when compiling the session factory.

Related

Register and Resolving Dependencies on Request Based on Param (Autofac WEB API)

I have an Application with autofac dependency injection and I wanted to use a specific dll extension based on the parameter I have on the request.
Here's my global.asax where I initialize autofac.
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterApiControllers(Assembly.GetExecutingAssembly());
containerBuilder.RegisterModule<ExModule>();
var container = containerBuilder.Build();
container.Resolve<IArtigoErp>();
Here's the autofac module where I load register my DLL's
public class ExModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
//Load DLL1 from folder and register it
RegistaDepedencias<IArtigoErp>(builder, "DLL1");
//Load DLL2 from folder and register it
RegistaDepedencias<IArtigoErp>(builder, "DLL2");
}
private void RegistaDepedencias<T>(ContainerBuilder builder, string NomeDll)
{
RegisterDep<T>(GetEnumerableTypes<T>(NomeDll), builder);
}
private void RegisterDep<T>(IEnumerable<Type> types, ContainerBuilder builder)
{
foreach (var t in types)
{
builder.RegisterType(t).As<T>();
}
}
private IEnumerable<Type> GetEnumerableTypes<T>(string NomeDll)
{
return Directory.EnumerateFiles(Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "Engine"))
.Where(x => x.Contains(NomeDll) && x.EndsWith(NomeDll +".dll"))
.Select(x => Assembly.LoadFrom(x))
.SelectMany(x => x.GetTypes()
.Where(t => typeof(T).IsAssignableFrom(t) && t.IsClass));
}
}
Both my DLL's have a class that extend from IArtigoErp.
So the ideia is, based on the parameter I get on my request, I want to run the method in either DLL1 or DLL2.
Example:
if(param == 1)
_artigoErp.GetLista(); // In DLL1
if(param == 2)
_artigoErp.GetLista(); // In DLL2
EDIT 1:
The parameter comes from the post method as it follows (Guid IdLoja)
public class ArtigoController : ApiController
{
private readonly IArtigoErp _artigoErp;
private readonly IArtigoLoja _artigoLoja;
public ArtigoController(IArtigoErp artigoErp, IArtigoLoja artigoLoja)
{
_artigoErp = artigoErp;
_artigoLoja = artigoLoja;
}
[Route("PostArtigos")]
public CallResponse PostArtigos([FromBody] Guid IdLoja)
{
}
}
I guess we can also process this in the begin_request method in global.asax
Thanks in advance.

webapi - dbcontext injection into fluentvalidation validator

Hello I am having a hard time passing an HTTP scoped object into a fluent validation validator. Everything works until I try to inject a service and then it throws the following error
No scope with a Tag matching 'AutofacWebRequest' is visible from the
scope in which the instance was requested. This generally indicates
that a component registered as per-HTTP request is being requested by
a SingleInstance() component
It comes down to the below snippet I think and I don't know how to mimic it in webapi
public Func<T> HttpRequestScopedFactoryFor<T>(){
return () => system.Web.Mvc.DependencyResolver.Current.GetService<T>();
}
IN MVC my autofac code looked like so
public class FluentValidationModule : Module
{
public Func<T> HttpRequestScopedFactoryFor<T>()
{
return () => System.Web.Mvc.DependencyResolver.Current.GetService<T>();
}
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterType<ApplicationDbContext>().AsSelf().InstancePerRequest();
builder.RegisterInstance(HttpRequestScopedFactoryFor<ApplicationDbContext>());
}
}
}
My FluentValidation validator code looked like so
public class RoleDTOValidator : AbstractValidator<RoleDTO>
{
readonly Func<ApplicationDbContext> _dbFactory;
public RoleDTOValidator(Func<ApplicationDbContext> dbFactory)
{
_dbFactory = dbFactory;
RuleFor(m => m.Id).NotEmpty();
RuleFor(m => m.Name).NotEmpty().Must(DoesNotExist).WithMessage("Another permission exists with that name."); ;
RuleFor(m => m.Description).NotEmpty();
RuleFor(m => m.Permissions).NotEmpty().SetCollectionValidator(new ApplicationRoleClaimValidator());
}
bool DoesNotExist(RoleDTO model, string name)
{
ApplicationDbContext db = _dbFactory();
int count = db.Roles.Count(item => item.Name == name);
return count == 0;
}
}
Any help is much appreciated.

MVC: I made a addquestion method in my repository that call .addobject(); and savechanges();

I made a method addquestion that calls addobject() and savechanges()
the Code inside the method is following:
public class AdminRepository
{
Model1Container db = new Model1Container();
CreateViewModel rep = new CreateViewModel();
public void Question addquestion() // <-- I dont know how the method should be
{
Question q = new Question();
q.QuestionText = rep.QuestionText;
db.Question.AddObject(q);
db.SaveChanges();
}
I know that the code is right but I dont know how to define the method.
Thanks in advance!
Best Regards!
You are specifying both a return type of void and Question
Since you aren't actually returning anything inside your method, the correct return type is void
public void addquestion()
{
//Your code here
}
public void AddQuestion()
{
....
}

Beginners Moq question on Verifying

I'm just playing around with Moq and I cannot work out how to get a call to Verify to work as expected. My problem seems to be that the method I'm calling on the SUT is not being called. Here's my code to test:
public class ImageHandler : BaseHttpHandler
{
public override void ProcessRequest(HttpContextBase context)
{
var person = new Person();
this.DoPerson(person);
context.Response.ContentType = "image/jpeg";
if (context.Request.RawUrl.ToLower().Contains("jellyfish.jpg"))
{
context.Response.TransmitFile(#"C:\Temp\jf.jpg");
}
else if (context.Request.RawUrl.ToLower().Contains("koala.jpg"))
{
context.Response.TransmitFile(#"C:\Temp\k.jpg");
}
else
{
context.Response.Write("File not found.");
}
}
public virtual void DoPerson(Person person)
{
}
}
Here is my MSpec test:
[Subject("Process")]
public class When_Given_Person
{
private static Mock<HttpContextBase> httpContext;
private static Mock<HttpRequestBase> httpRequest;
private static Mock<HttpResponseBase> httpResponse;
private static Mock<ImageHandler> mockSut;
private static BaseHttpHandler sut;
private Establish context = () =>
{
httpContext = new Mock<HttpContextBase>();
httpResponse = new Mock<HttpResponseBase>();
httpRequest = new Mock<HttpRequestBase>();
mockSut = new Mock<ImageHandler>();
httpContext.SetupGet(context => context.Response).Returns(httpResponse.Object);
httpContext.SetupGet(context => context.Request).Returns(httpRequest.Object);
httpRequest.SetupGet(r => r.RawUrl).Returns("http://logicsoftware/unkown.jpg");
sut = mockSut.Object;
};
private Because of = () => sut.ProcessRequest(httpContext.Object);
private It should_call_person_with_expected_age = () =>
{
mockSut.Verify(s => s.DoPerson(Moq.It.IsAny<Person>()),Times.AtLeastOnce());
};
}
This is really basic stuff, nothing too fancy. Now, when I run the test I get:
Expected invocation on the mock at least once, but was never
performed: s => s.DoPerson(It.IsAny()) No setups configured.
I believe this is due to the fact that sut.ProcessRequest() is not actually called - I have a breakpoint at the start of ProcessRequest(), but it's never hit. Can someone show me how to setup my mockSut so that ProcessRequest() is called.
Cheers.
Jas.
When you make a Mock of an object with Moq, it will mock the whole object and set it up to return defaults or do nothing on every method and property. So sut.ProcessRequest, won't actually do anything: DoPerson will never be called.
You'll only want to mock out dependencies to the classes you want to test, never the class itself.

How to pass a mvc-mini-profiler connection to a base class from MVC3

Given this snippet of code
public abstract class Foo
{
private static SqlConnection _sqlConnection;
protected SqlConnection GetOpenConnection()
{
if (_sqlConnection == null)
{
_sqlConnection = new SqlConnection("connection string");
}
return _sqlConnection;
}
protected abstract void Execute();
}
public class FooImpl : Foo
{
protected override void Execute()
{
var myConn = GetOpenConnection();
var dog = myConn.Query<dynamic>("select 'dog' Animal");
var first = dog.First();
string animalType = first.Animal;
// more stuff here
}
}
How would you wrap the connection in a profiled connection if you don't have access to the connection creation process? Rewrite the code in the super class and wrap it there? This would involve changing hundreds of classes that inherit from the base. I'd prefer a way to change the base class, with as little changes necessary to the supers.
Thank you,
Stephen
Well after a bit of trial and error I compromised and added a ref to MvcMiniProfiler in the base library and changed the connection code a bit.
protected DbConnection GetOpenConnection()
{
if (_connection == null)
{
_connection = new SqlConnection(ConfigurationManager.ConnectionStrings["connection string "].ConnectionString);
_connection.Open();
}
return MvcMiniProfiler.Data.ProfiledDbConnection.Get(_connection, MiniProfiler.Current);
}
private static SqlConnection _connection;
This works for both hosting in the MVC project (for profiling purposes, where we don't have that capability (QA/Prod Databases)) and WPF/Windows Service

Resources