PostSharp when using DataContractSerializer? - wcf

I have an Aspect that implements INotifyPropertyChanged on a class. The aspect includes the following:
[OnLocationSetValueAdvice, MethodPointcut("SelectProperties")]
public void OnPropertySet(LocationInterceptionArgs args)
{
var currentValue = args.GetCurrentValue();
bool alreadyEqual = (currentValue == args.Value);
// Call the setter
args.ProceedSetValue();
// Invoke method OnPropertyChanged (ours, the base one, or the overridden one).
if (!alreadyEqual)
OnPropertyChangedMethod.Invoke(args.Location.Name);
}
This works fine when I instantiate the class normally, but I run into problems when I deserialize the class using a DataContractSerializer. This bypasses the constructor, which I'm guessing interferes with the way that PostSharp sets itself up. This ends up causing a NullReferenceException in an intercepted property setter, but before it has called the custom OnPropertySet, so I'm guessing it interferes with setting up the LocationInterceptionArgs.
Has anyone else encountered this problem? Is there a way I can work around it?
I did some more research and discovered I can fix the issue by doing this:
[OnDeserializing]
private void OnDeserializing(StreamingContext context)
{
AspectUtilities.InitializeCurrentAspects();
}
I thought, okay, that's not too bad, so I tried to do this in my Aspect:
private IEnumerable<MethodInfo> SelectDeserializing(Type type)
{
return
type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(
t => t.IsDefined(typeof (OnDeserializingAttribute), false));
}
[OnMethodEntryAdvice, MethodPointcut("SelectDeserializing")]
public void OnMethodEntry(MethodExecutionArgs args)
{
AspectUtilities.InitializeCurrentAspects();
}
Unfortunately, even though it intercepts the method properly, it doesn't work. I'm thinking the call to InitializeCurrentAspects isn't getting transformed properly, since it's now inside the Aspect rather than directly inside the aspect-enhanced class. Is there a way I can cleanly automate this so that I don't have to worry about calling this on every class that I want to have the Aspect?

Support for serialization has been added lately and is available as a hotfix.
http://www.sharpcrafters.com/downloads/postsharp-2.0/hot-fixes

Related

How do I mock Func<T> factory dependency to return different objects using AutoMock?

I'm trying to write a test for a class that has a constructor dependency on Func<T>. In order to complete successfully the function under test needs to create a number of separate objects of type T.
When running in production, AutoFac generates a new T every time factory() is called, however when writing a test using AutoMock it returns the same object when it is called again.
Test case below showing the difference in behaviour when using AutoFac and AutoMock. I'd expect both of these to pass, but the AutoMock one fails.
public class TestClass
{
private readonly Func<TestDep> factory;
public TestClass(Func<TestDep> factory)
{
this.factory = factory;
}
public TestDep Get()
{
return factory();
}
}
public class TestDep
{}
[TestMethod()]
public void TestIt()
{
using var autoMock = AutoMock.GetStrict();
var testClass = autoMock.Create<TestClass>();
var obj1 = testClass.Get();
var obj2 = testClass.Get();
Assert.AreNotEqual(obj1, obj2);
}
[TestMethod()]
public void TestIt2()
{
var builder = new ContainerBuilder();
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
var container = builder.Build();
var testClass = container.Resolve<TestClass>();
var obj1 = testClass.Get();
var obj2 = testClass.Get();
Assert.AreNotEqual(obj1, obj2);
}
AutoMock (from the Autofac.Extras.Moq package) is primarily useful for setting up complex mocks. Which is to say, you have a single object with a lot of dependencies and it's really hard to set that object up because it doesn't have a parameterless constructor. Moq doesn't let you set up objects with constructor parameters by default, so having something that fills the gap is useful.
However, the mocks you get from it are treated like any other mock you might get from Moq. When you set up a mock instance with Moq, you're not getting a new one every time unless you also implement the factory logic yourself.
AutoMock is not for mocking Autofac behavior. The Func<T> support where Autofac calls a resolve operation on every call to the Func<T> - that's Autofac, not Moq.
It makes sense for AutoMock to use InstancePerLifetimeScope because, just like setting up mocks with plain Moq, you need to be able to get the mock instance back to configure it and validate against it. It would be much harder if it was new every time.
Obviously there are ways to work around that, and with a non-trivial amount of breaking changes you could probably implement InstancePerDependency semantics in there, but there's really not much value in doing that at this point since that's not really what this is for... and you could always create two different AutoMock instances to get two different mocks.
A much better way to go, in general, is to provide useful abstractions and use Autofac with mocks in the container.
For example, say you have something like...
public class ThingToTest
{
public ThingToTest(PackageSender sender) { /* ... */ }
}
public class PackageSender
{
public PackageSender(AddressChecker checker, DataContext context) { /* ... */ }
}
public class AddressChecker { }
public class DataContext { }
If you're trying to set up ThingToTest, you can see how also setting up a PackageSender is going to be complex, and you'd likely want something like AutoMock to handle that.
However, you can make your life easier by introducing an interface there.
public class ThingToTest
{
public ThingToTest(IPackageSender sender) { /* ... */ }
}
public interface IPackageSender { }
public class PackageSender : IPackageSender { }
By hiding all the complexity behind the interface, you now can mock just IPackageSender using plain Moq (or whatever other mocking framework you like, or even creating a manual stub implementation). You wouldn't even need to include Autofac in the mix because you could mock the dependency directly and pass it in.
Point being, you can design your way into making testing and setup easier, which is why, in the comments on your question, I asked why you were doing things that way (which, at the time of this writing, never did get answered). I would strongly recommend designing things to be easier to test if possible.

AsyncLocal<T> doesn't reach controllers

I don't quite fully understand this situation, where AsyncLocal instance is set at a certain point in the AuthenticationHandler, but does not reach the controller, when it is injected into the constructor.
I've made it similar to how IHttpContextAccessor works, but still nowhere near. However, if I set the AsyncLocal from a Middleware, it reaches the controller. Also, setting the HttpContext.Items property from AuthenticationHandler works just fine.
Question: How is HttpContext able to retain Items property contents all the way, and is ASP.NET runtime disposing the captured ExecutionContext of my DomainContextAccessor for some security reason because of where it is being set at?
I've made a sample app to demo this use case. I'd really appreciate someone shedding the light on this problem.
You already have a good answer on "how should I fix this?" Here's more of a description of why it's behaving this way.
AsyncLocal<T> has the same semantics as logging scopes. Because it has those same semantics, I always prefer to use it with an IDisposable, so that the scope is clear and explicit, and there's no weird rules around whether a method is marked async or not.
For specifics on the weird rules, see this. In summary:
Writing a new value to an AsyncLocal<T> sets that value in the current scope.
Methods marked async will copy their scope to a new scope the first time it's written to (and it's the new scope that is modified).
I've made it similar to how IHttpContextAccessor works, but still nowhere near.
I don't recommend copying the design of IHttpContextAccessor. It works... for that very specific use case. If you want to use AsyncLocal<T>, then use a design like this:
static class MyImplicitValue
{
private static readonly AsyncLocal<T> Value = new();
public static T Get() => Value.Value;
public static IDisposable Set(T newValue)
{
var oldValue = Value.Value;
Value.Value = newValue;
return new Disposable(() => Value.Value = oldValue);
}
}
usage:
using (MyImplicitValue.Set(myValue))
{
// Code in here can get myValue from MyImplicitValue.Get().
}
You can wrap that into an IMyImplicitValueAccessor if desired, but note that any "setter" logic should be using the IDisposable pattern as shown.
AsyncLocal instance is set at a certain point in the AuthenticationHandler, but does not reach the controller
That's because your AuthenticationHandler sets the value but doesn't call the controller after setting that value (and it shouldn't).
However, if I set the AsyncLocal from a Middleware, it reaches the controller.
That's because middleware is calls the next middleware (eventually getting to the controller). I.e., middleware is structured like this:
public async Task InvokeAsync(HttpContext context)
{
using (implicitValue.Set(myValue))
{
await _next(context);
}
}
So the controllers are in the scope of when that AsyncLocal<T> value was set.
How is HttpContext able to retain Items property contents all the way
Items is just a property bag. It doesn't have anything to do with AsyncLocal<T>. It exists because it's a property on HttpContext, and it persists because the same HttpContext instance is used throughout the request.
is ASP.NET runtime disposing the captured ExecutionContext of my DomainContextAccessor for some security reason because of where it is being set at?
Not exactly. The AsyncLocal<T> is being set just fine; it's just that the controllers are not called within the scope of that AsyncLocal<T> being set.
So what must be happening is there is a execution context change which wipes that value out. It works with in the middleware because your controller is in the same execution context as your middleware.
Change your code to this:
private static void DomainContextChangeHandler(AsyncLocalValueChangedArgs<DomainContextHolder> args)
{
Trace.WriteLine($"ThreadContextChanged: {args.ThreadContextChanged}");
Trace.WriteLine($"Current: {args.CurrentValue?.GetHashCode()}");
Trace.WriteLine($"Previous: {args.PreviousValue?.GetHashCode()}");
Trace.WriteLine($"Thread Id: {Thread.CurrentThread.ManagedThreadId}");
}
Now you can see when the context changes.
Here is something you could do:
private static void DomainContextChangeHandler(AsyncLocalValueChangedArgs<DomainContextHolder> args)
{
if (args.ThreadContextChanged && (args.PreviousValue != null) && (args.CurrentValue == null))
{
Trace.WriteLine(
"***** Detected context change with a previous value but setting current " +
"value to null. Resetting value to previous.");
_domainContextCurrent.Value = args.PreviousValue;
return;
}
Trace.WriteLine($"ThreadContextChanged: {args.ThreadContextChanged}");
Trace.WriteLine($"Current: {args.CurrentValue?.GetHashCode()}");
Trace.WriteLine($"Previous: {args.PreviousValue?.GetHashCode()}");
Trace.WriteLine($"Thread Id: {Thread.CurrentThread.ManagedThreadId}");
}
But, that kinda defeats the purpose of using AsyncLocal as your backing store.
My suggestion is you drop the AsyncLocal and use normal class-scoped storage:
namespace WebApp.Models
{
public interface IDomainContextAccessor
{
DomainContext DomainContext { get; set; }
}
public sealed class DomainContextAccessor : IDomainContextAccessor
{
public DomainContext DomainContext { get; set; }
}
}
And inject it as scoped instead of singleton:
services.AddScoped<IDomainContextAccessor, DomainContextAccessor>();
It will do exactly what you want without any kludges -- AND, the future you (or devs) will absolutely understand what's going on and why it is the way it is.
No middleware, no AsyncLocal funny-business. It just works.
Your answer is here:
.net core AsyncLocal loses its value
In your DomainContextAccessor class when you set new value in this line: _domainContextCurrent.Value = new DomainContextHolder { Context = value };
you create NEW ExecutionContext in current thread and child threads.
So I suppose that mvc runs like this:
Middleware thread => you set value => some child thread with Controller execution which sees parent changes
But for UserAuthenticationHandler it feels it works like this:
Some controller factory creates controller with injected IDomainContextAccessor (1 context) => mvc executes auth handler in child task where you set value and create 2 context. But it's value does not go UP to parent (where controller 1 context exists) because you create new context when you set value. Even more your code gets parents context, gets reference to its value and makes property Context = null, so you will get null in Controller.
So to fix this you need to change your code:
public class DomainContext
{
private static AsyncLocal<DomainContext> _contextHolder = new AsyncLocal<DomainContext>();
public static DomainContext Current
{
get
{
return _contextHolder.Value;
}
}
public Job JobInfo { get; set; }
public static void InitContext()
{
_contextHolder.Value = new DomainContext();
}
}
//using in middleware:
DomainContext.InitContext();
//using in auth handler:
DomainContext.Current.JobInfo = ...
In example above you don't change DomainContext reference in _contextHolder.Value;
It remains the same but you only change value of JobInfo in it later in auth handler

Using Test Doubles with DbEntityEntry and DbPropertyEntry

I am using the new Test Doubles in EF6 as outlined here from MSDN . VS2013 with Moq & nUnit.
All was good until I had to do something like this:
var myFoo = context.Foos.Find(id);
and then:
myFoo.Name = "Bar";
and then :
context.Entry(myFoo).Property("Name").IsModified = true;
At this point is where I get an error:
Additional information: Member 'IsModified' cannot be called for
property 'Name' because the entity of type
'Foo' does not exist in the context. To add an
entity to the context call the Add or Attach method of
DbSet.
Although, When I examine the 'Foos' in the context with an AddWatch I can see all items I Add'ed before running the test. So they are there.
I have created the FakeDbSet (or TestDbSet) from the article. I am putting each FakeDbSet in the FakeContext at the constructor where each one gets initialized. Like this:
Foos = new FakeDbSet<Foo>();
My question is, is it possible to work with the FakeDbSet and the FakeContext with the test doubles scenario in such a way to have access to DbEntityEntry and DBPropertyEntry from the test double? Thanks!
I can see all items I Add'ed before running the test. So they are there.
Effectively, you've only added items to an ObservableCollection. The context.Entry method reaches much deeper than that. It requires a change tracker to be actively involved in adding, modifying and removing entities. If you want to mock this change tracker, the ObjectStateManager (ignoring the fact that it's not designed to be mocked at all), good luck! It's got over 4000 lines of code.
Frankly, I don't understand all these blogs and articles about mocking EF. Only the numerous differences between LINQ to objects and LINQ to entites should be enough to discourage it. These mock contexts and DbSets build an entirely new universe that's a source of bugs in itself. I've decided to do integrations test only when and wherever EF is involved in my code. A working end-to-end test gives me a solid feeling that things are OK. A unit test (faking EF) doesn't. (Others do, don't get me wrong).
But let's assume you'd still like to venture into mocking DbContext.Entry<T>. Too bad, impossible.
The method is not virtual
It returns a DbEntityEntry<T>, a class with an internal constructor, that is a wrapper around an InternalEntityEntry, which is an internal class. And, by the way, DbEntityEntry doesn't implement an interface.
So, to answer your question
is it possible to (...) have access to DbEntityEntry and DBPropertyEntry from the test double?
No, EF's mocking hooks are only very superficial, you'll never even come close to how EF really works.
Just abstract it. If you are working against an interface, when creating your own doubles, put the modified stuff in a seperate method. My interface and implementation (generated by EF, but I altered the template) look like this:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Model
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public interface IOmt
{
DbSet<DatabaseOmtObjectWhatever> DatabaseOmtObjectWhatever { get; set; }
int SaveChanges();
void SetModified(object entity);
void SetAdded(object entity);
}
public partial class Omt : DbContext, IOmt
{
public Omt()
: base("name=Omt")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<DatabaseOmtObjectWhatever> DatabaseOmtObjectWhatever { get; set; }
public void SetModified(object entity)
{
Entry(entity).State = EntityState.Modified;
}
public void SetAdded(object entity)
{
Entry(entity).State = EntityState.Added;
}
}
}

IntelliJ Idea's Law of Demeter inspection. False positive or not?

Suppose the next class
interface Thing {
void doSomething();
}
public class Test {
public void doWork() {
//Do smart things here
...
doSomethingToThing(index);
// calls to doSomethingToThing might happen in various places across the class.
}
private Thing getThing(int index) {
//find the correct thing
...
return new ThingImpl();
}
private void doSomethingToThing(int index) {
getThing(index).doSomething();
}
}
Intelli-J is telling me that I'm breaking the law of demeter since DoSomethingToThing is using the result of a function and supposedly you can only invoke methods of fields, parameters or the object itself.
Do I really have to do something like this:
public class Test {
//Previous methods
...
private void doSomething(Thing thing) {
thing.doSomething();
}
private void doSomethingToThing(int index) {
doSomething(getThing(index));
}
}
I find that cumbersome. I think the law of demeter is so that one class doesn't know the interior of ANOTHER class, but getThing() is of the same class!
Is this really breaking the law of demeter? is this really improving design?
Thank you.
Technically, this is breaking the Demeter's laws. Though I would contest that private functions should be considered for LoD-F, as supposedly they are not accessible from outside. At the same time, it's not really breaking Demeter's laws, if 'thing' is owned by Test. But in Java, the only way to get to thing may be through a getter, which takes this back to that technicality (no clear separation between getter and action methods).
I would say, do this:
public class Test {
private Thing getThing(int index) {
//find the thing
return thing;
}
private void DoSomethingToThing(Thing thing) {
thing.doSomething();
}
private void DoSomethingToThing(int index) {
DoSomethingToThing(getThing(index));
}
}
Or, probably better, have the caller use thing directly. Which is possible if Test's function is to produce or expose things, rather than being the intermediary to manipulate thing.
IntelliJ is not detecting object instantiation correctly.
Wikipedia (what IDEA links to) describes that you can call objects created in the current context.
That's what I do, but still I get the warning on getMajor():
Version version = Loader.readVersion(inputStream); // Instantiates a new Version
if (version.getMajor() != 2)
throw new IOException("Only major version 2 is supported");
IDEA's inspection offers an option to ignore calls to 'library' methods. In my case, Loader.readVersion() is a library method, however it's located inside the current project (the project must be self-supporting). IDEA thinks it's not a library method.
Since the mechanism of this inspection is inadequate/incomplete/naive (like with MANY of IDEA's inspections btw), the only solution is disabling it and attempt to avoid these situations manually.

How to correctly dispose objects registered with Autofac

I've implemented Unit of Work/Repository pattern, as described here, but I'm also using autofac and constructor injection, so I registered UnitOfWork and DbContext (PsyProfContext) class like this:
builder.Register(context => new PsyProfContext()).InstancePerHttpRequest();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest();
And everything works great!
Except for one thing: I'm also using enterprise library logging block, and I have implemented CustomTraceListener which is using Entity Framework to write log entry into the database.
My controller looks like this (it is empty because at the moment I just tried to verify if all the things (IoC, logging, entity framework) are working):
public class HomeController : Controller
{
private readonly UnitOfWork unitOfWork;
public HomeController(IUnitOfWork unitOfWork)
{
this.unitOfWork = (UnitOfWork) unitOfWork;
}
//
// GET: /Home/
public ActionResult Index()
{
throw new HttpException();
return View();
}
protected override void Dispose(bool disposing)
{
unitOfWork.Dispose();
base.Dispose(disposing);
}
}
And in the Write method of the CustomTraceListener class, I've tried to Resolve UnitOfWork:
DependencyResolver.Current.GetService<IUnitOfWork>() as UnitOfWork;
But I get an instance which is already disposed! so I've put some breakpoints and found out that Dispose method of the controller is called before the Write method of the CustomTraceListener class, so in the end I didn't found other solution than using DbContext (PsyProfContext) directly:
public override void Write(object o)
{
using (var conext = new PsyProfContext())
{
var customLogEntry = o as CustomLogEntry;
if (customLogEntry != null)
{
var logEntry = new LogEntry
{
//a bunch of properties
};
conext.Exceptions.Add(logEntry);
conext.SaveChanges();
}
}
}
But I don't like this solution! What's the point to use UnitOfWork and Repository pattern if you access DbContext object directly. Or what's the point in using DI in project if you create a registered object manually in some cases.
So I wanted to hear your opinion, about how to deal with this kind of situations? Is my current implementation fine, or it is definitely wrong and I should think about another one.
Any help will be greatly appreciated and any ideas are welcome!
It looks like you may have a couple of problems.
First, if you're manually disposing the unit of work object in your controller, your controller should take an Owned<IUnitOfWork> in the constructor. When the request lifetime is disposed it will automatically dispose of any IDisposable components - including the controller and any resolved dependencies - unless you specify somehow that you're going to take over ownership of the lifetime. You can do that by using Owned<T>.
public class HomeController : Controller
{
Owned<IUnitOfWork> _uow;
public HomeController(Owned<IUnitOfWork> uow)
{
this._uow = uow;
}
protected override void Dispose(bool disposing)
{
if(disposing)
{
this._uow.Dispose();
}
base.Dispose(disposing);
}
}
(Note a minor logic fix in the Dispose override there - you need to check the value of disposing so you don't double-dispose your unit of work.)
Alternatively, you could register your units of work as ExternallyOwned, like
builder
.RegisterType<UnitOfWork>()
.As<IUnitOfWork>()
.ExternallyOwned()
.InstancePerHttpRequest();
ExternallyOwned also tells Autofac that you'll take control of disposal. In that case, your controller will look like it does already. (Generally I like to just let Autofac do the work, though, and not take ownership if I can avoid it.)
In fact, looking at the way things are set up, you might be able to avoid the disposal problem altogether if you let Autofac do the disposal for you - the call to DependencyResolver would return the unit of work that isn't disposed yet and it'd be OK.
If that doesn't fix it... you may want to add some detail to your question. I see where your controller is using the unit of work class, but I don't see where it logs anything, nor do I see anything in the listener implementation that's using the unit of work.
(Also, as noted in the first comment on your question, in the constructor of your controller you shouldn't be casting your service from IUnitOfWork to UnitOfWork - that's breaking the abstraction that the interface was offering in the first place.)