This is my method, I am trying to validate componentToSave
(or access method parameter values) and throw an exception before method body even runs.
public Component SaveComponent(Component componentToSave) {
...
}
I tried using PostSharp but it is not free and also there were other libraries that rely on AutoFac as IoC but in my current setup I am using dotnet core's built-in dependency injection.
I tried
NConcern
and it relies onCNeptune
andCNeptune
itself relies on a.exe
file for post-compile binding and I currently use Linux for both development and production so I cannot use it, even I tried testing with it on windows but could not get it to work with dotnet core.I tried this approach (i.e.
ActionFilter
andServiceFilter
) but I only got it working if[ServiceFilter(typeof(LoggingActionFilter))]
is over controller not any other method (i.e.SaveComponent
method).I tried using
RealProxy
but apparently, it is not supported in dotnet core.
I am just lost, maybe I am over complicating the problem but there should be a way. Any help would be greatly appreciated.
Look into CQS, decorators and SimpleInjector. If you promote methods to classes, you can have the class dedicated to one thing (SOLID). Then you can add cross cutting concerns on decorators that will have the same interface as the implementation, but they essential chain the calls. if validation decorator fails, then your main logic won't ever be called. You can even add all exception handling here and any logging or retry logic or caching.
Edit
Sorry, was on mobile before! :)
For an example, I'll use your method here. Normally with CQS, you'd have a generic interface for all your queries (read-only) and commands (change state). That way, all your logic ends up going through a IQueryHandler or ICommandHandler so you can add cross cutting concerns to ALL your logic all at once. However, I'll make an example specific to your question.
public interface ISaveComponent
{
Component SaveComponent(Component componentToSave);
}
public class SaveComponent : ISaveComponent
{
public Component SaveComponent(Component componentToSave)
{
// Do your work here
}
}
public class SaveComponentValidation : ISaveComponent
{
private readonly ISaveComponent _saveComponent;
public SaveComponentValidation(ISaveComponent saveCompnent)
{
_saveComponent = saveCompnent;
}
public Component SaveComponent(Component componentToSave)
{
// Do Validation here
return _saveComponent.SaveComponent(componentToSave);
}
}
If you let SimpleInjector (IoC/DI) handle the decorations for you, then you just have to register them in one line of code like this:
container.RegisterDecorator(typeof(ISaveComponent), typeof(SaveComponentValidation));
Otherwise, you would have to manually create them like this:
public class Program
{
public static void Main()
{
ISaveComponent handler = new SaveComponentValidation(new SaveComponent());
handler.SaveComponent(new Component());
}
}
来源:https://stackoverflow.com/questions/48124782/aop-for-c-sharp-dotnet-core-2-0-access-method-parameter-values-before-method-bo