Autofac + Castle DynamicProxy: Order of interceptors - aop

I'm using Castle DynamicProxy with Autofac. I have an object for which I've created a proxy, and I have two interceptors that act on the proxy, one for logging an exception and the second for for altering the return value of the method. The registration code looks like the following:
var builder = new ContainerBuilder();
builder.Register(c => c.Resolve<ProxyGenerator>()
.CreateClassProxy<Foo>(
c.Resolve<ResultProcessorInterceptor>(),
c.Resolve<ExceptionLoggingInterceptor>()))
.As<Foo>();
By supplying the arguments in this order, I'm finding that I get the result that I want, i.e., the exception is logged and the result is processed. If I reverse the order of the arguments, the logging doesn't occur.
My question, then: registered in this way, are the interceptors guaranteed to execute in the same order every time? Or is there a better way to ensure that the order will be what I intend every time?
FWIW, I looked at the IInterceptorSelector interface. Perhaps I'm missing something--which is not unlikely--but it looked like that wasn't relevant in this case. But I'd be happy to be corrected if I'm wrong.
I can supply a longer code sample if necessary.
musicologyman

Yes, the interceptors will be by default executed in the provided order for every intercepted method.
As you correctly noted you can override it on a per-method basis using IInterceptorSelector if needed.

Related

What is the point of IStartupFilter in asp.net core?

IStartupFilter is the basis of a mechanism for libraries to add middleware to the app. According to the Docs "IStartupFilter is useful to ensure that a middleware runs before or after middleware added by libraries at the start or end of the app's request processing pipeline".
Does the mechanism allow you to manipulate the pipeline in any way that can't be done from Startup.Configure()?
If the point is modularity then you just seem to be trading coupling through Startup.Configure() for coupling via the IServicesCollection (a call to DI is required). In the simple case (as per the example) a call to services.AddTransient<IStartupFilter, ...>() can be removed from ConfigureServices() and app.AddMiddleware<MyMiddleware>() can be added to achieve the same functionality with less complexity and magic.
Is the main point of the mechanism to allow the library to apply conditions as to what middleware should be included? If so, it seems to lack asp.net core's customary economy and clarity of design.
In the simple case (as per the example) a call to services.AddTransient<IStartupFilter, ...>() can be removed from ConfigureServices() and app.AddMiddleware() can be added to achieve the same functionality with less complexity and magic.
That's not true.
There is a big difference between using IStartupFilter and using a middleware. A middleware is part of the request pipeline, which means it gets executed on every request. On the other hand, IStartupFilter gets executed just once when the application starts (not on every request).
To answer my own question, I think that the main use case is to enable the framework to encorporate assemblies that were not known at build time. The docs cover this in the aspnetcore/Fundamentals/Host nhance an app from an external assembly in ASP.NET Core with IHostingStartup. (Although the documentation makes no mention of IStartupFilter the associated StartupDiagnostics sample project does.
IStartupFilter is usually used when you do not want any intervention from app’s author i.e. you don’t want that app.Usexxxx() to get called but a different component should configure that middleware. Now, consider a scenario where you want to execute certain code even if the request pipeline is not executed.
Lets take a URI which does not exist and returns 404 error, in that case request processing pipeline won’t be executed but startup filter will be.
A simple answer is no, it doesn't add any new functionality.
The point behind the IStartupFilter is to run some stuff in the pre-defined order independently on how yours Startup.Configure method changes. It simply creates a sequence of methods they do actions on IApplicationBuilder (WebHostBuilder) to build the middleware pipeline. You can define action that will perform before or after the Startup.Configure method is called.
Your IStartupFilter implementation will look similarly to this:
public class ExampleStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
// This will run before the Startup.Configure
builder.UseMiddleware<PreStartupConfigureRegisteredMiddleware>();
// This is Startup.Configure (or the next IStartupFilter.Configure in the sequence)
next(builder);
// This will run after Startup.Configure
builder.UseMiddleware<AfterStartupConfigureRegisteredMiddleware>();
};
}
}
Arguably, as you have to register your IStartupFilter in the Startup.ConfigureServices method and the order the filters are registered is the order they will be performed, there is not much difference compare to the order of direct registrations of UseMiddleware in Startup.Configure.
The only benefit I can see is that you can register something that has absolutely run the first or the last in the pipeline, no matter what other middlewares you use. Then you don't have to worry about changes in the Configure method. It should, however, be used very scarcely.
Very good blog post explaining how the IStartupFilter works has been written by Andrew Lock, check it out here:
https://andrewlock.net/exploring-istartupfilter-in-asp-net-core/
One thing Andrew points out is that you can register filter to run it prior to the AutoRequestServicesStartupFilter registered automatically by the WebHostBuilder. Not that I would be aware of an example where this would have a practical use.

.net Core 2.0 OData - EnableQuery attribute not allowing operations

I am trying to use Microsoft.AspNetCore.OData, v7.0.0.0-beta1, in a simple project.
I am failing to filter, select, and use top or skip.
Overriding the ValidateQuery of the EnableQueryAttribute, I can successfully perform these type of operations so I believe the library is buggy.
I could not find the right channel to report the issue, can anyone help?
The sample code to reproduce is available here: https://github.com/norcino/AspNetCoreSamples/tree/master/SampleODataApp
The solution to the problem was the actual initialization of the MVC route builder.
Like in the .net framework version it is possible to specify which operation is allowed for OData query. In the example below I am whitelisting everything but you can do a more fine tuning passing an instance of QueryOptionSetting.
app.UseMvc(routeBuilder =>
{
routeBuilder
.Select()
.Expand()
.Filter()
.OrderBy(QueryOptionSetting.Allowed)
.MaxTop(2000)
.Count();
routeBuilder.EnableDependencyInjection();
});
Note that, the attribute [HttpGet, EnableQuery(AllowedOrderByProperties = "Id")], will effectively enforce the order by to the sole Id property specified in the attribute, but first you need to enable all from the configuration.

ServiceStack and NHibernate Unit Of Work Pattern

Long story as brief as possible...
I have an existing application that I'm trying to get ServiceStack into to create our new API. This app is currently an MVC3 app and uses the UnitOfWork pattern using Attribute Injection on MVC routes to create/finalize a transaction where the attribute is applied.
Trying to accomplish something similar using ServiceStack
This gist
shows the relevant ServiceStack configuration settings. What I am curious about is the global request/response filters -- these will create a new unit of work for each request and close it before sending the response to the client (there is a check in there so if an error occurs writing to the db, we return an appropriate response to the client, and not a false "success" message)
My questions are:
Is this a good idea or not, or is there a better way to do
this with ServiceStack.
In the MVC site we only create a new unit
of work on an action that will add/update/delete data - should we do
something similar here or is it fine to create a transaction only to retrieve data?
As mentioned in ServiceStack's IOC wiki the Funq IOC registers dependencies as a singleton by default. So to register it with RequestScope you need to specify it as done here:
container.RegisterAutoWiredAs<NHibernateUnitOfWork, IUnitOfWork()
.ReusedWithin(ReuseScope.Request);
Although this is not likely what you want as it registers as a singleton, i.e. the same instance returned for every request:
container.Register<ISession>((c) => {
var uow = (INHibernateUnitOfWork) c.Resolve<IUnitOfWork>();
return uow.Session;
});
You probably want to make this:
.ReusedWithin(ReuseScope.Request); //per request
.ReusedWithin(ReuseScope.None); //Executed each time its injected
Using a RequestScope also works for Global Request/Response filters which will get the same instance as used in the Service.
1) Whether you are using ServiceStack, MVC, WCF, Nancy, or any other web framework, the most common method to use is the session-per-request pattern. In web terms, this means creating a new unit of work in the beginning of the request and disposing of the unit of work at the end of the request. Almost all web frameworks have hooks for these events.
Resources:
https://stackoverflow.com/a/13206256/670028
https://stackoverflow.com/search?q=servicestack+session+per+request
2) You should always interact with NHibernate within a transaction.
Please see any of the following for an explanation of why:
http://ayende.com/blog/3775/nh-prof-alerts-use-of-implicit-transactions-is-discouraged
http://www.hibernatingrhinos.com/products/nhprof/learn/alert/DoNotUseImplicitTransactions
Note that when switching to using transactions with reads, be sure to make yourself aware of NULL behavior: http://www.zvolkov.com/clog/2009/07/09/why-nhibernate-updates-db-on-commit-of-read-only-transaction/#comments

Ninject not creating a new instance with constructor arguments in WCF

Here is the scenario. I have a WCF service, when this service is called it passes control to an instance of another class (created via Ninject). In that class I need to do some work, specifically with Entity Framework and repositories. To cut a long story short, I have the following binding declared.
Bind<IGenericProductRepository>()
.To<GenericProductRepository>()
.WithConstructorArgument( "context", new StagingDataContext());
When I want to use this repository I have the following.
using (var genericProductRepository = IoC.Resolve<IGenericProductRepository>())
The problem is, that I only get a new instance of genericProductRepository if it's a brand new request, if the method is called multiple times in the same request I get an error stating that the context (the EF context) is already disposed, this is because it seems like I am getting the same instance back that was already disposed in the using statement. To explain it another way, using the Microsoft WCF Test Client, if I invoke it the first time, the code runs fine, if I push the invoke button again (without restarting the test client, i.e. the same request) then it throws this error about it being disposed already.
I have tried to play around with the various "scopes" that come with Ninject, but clearly I am missing something.
So my basic question is, how do I get a new repository whenever it hits that line, instead of using the same one ? Help would be greatly appreciated, I'm really trying to push for my company to adopt Ninject and drop Spring.
Look at your binding again. Even without any knowledge about Ninject you should notice that the instance of your context is created exactly once at the time the binding is defined. But what you want is have a new context on every resolve. Best it is done by not using WithConstructorArgument and let Ninject create the instance. Therefore you have to define a additional binding for the type of context. If this is not possible for some reason you have to use the lazy version of WithConstructorArgument
WithConstructorArgument("context", ctx => new StagingDataContext())
Furthermore, you might want to try The WCF extension for Ninject:
https://github.com/ninject/ninject.extensions.wcf
That way you can get rid of the ServiceLocator like usage.

Inject behavior into WCF After or During identification of WebGet Method to call

I am trying to solve a problem where i have a WCF system that i have built a custom Host, Factory host, instance providers and service behaviors to do authentication and dependency injection.
However I have come up with a problem at the authorisation level as I would like to do authorisation at the level of the method being called.
For example
[OperationContract]
[WebGet(UriTemplate = "/{ConstituentNumber}/")]
public Constituent GetConstituent(string ConstituentNumber)
{
Authorisation.Factory.Instance.IsAuthorised(MethodBase.GetCurrentMethod().Name, WebOperationContext.Current.IncomingRequest.Headers["Authorization"]);
return constituentSoapService.GetConstituentDetails(ConstituentNumber);
}
Basically I now have to copy the Call to IsAuthorised across every web method I have. This has two problems.
It is not very testable. I Have extracted the dependecies as best that I can. But this setup means that I have to mock out calls to the database and calls to the
WebOperationContext.
I Have to Copy that Method over and over again.
What I would like to know is, is there a spot in the WCF pipeline that enables me to know which method is about to be called. Execute the authorisation request. and then execute the method based on the true false value of the authorisation response.
Even better if i can build an attribute that will say how to evaluate the method.
One possible way to do what you want might be by intercepting requests with a custom IDispatchMessageInspector (or similar WCF extension point).
The trick there, however, is that all you get is the raw message, but not where it will be processed (i.e. the method name). With a bit of work, however, it should be possible to build a map of URIs/actions and the matching method names (this is how you'd do it for SOAP, though haven't tried it for WebGet/WebInvoke yet).