Using PostSharp to intercept ADO.Net - entity-framework

I have quite a large code base using a variety of different ADO technologies (i.e. some EF and in some cases using ADO.Net directly).
I'm wondering if there is any way to globally intercept any ADO.Net calls so that I can start auditing information - exact SQL statements that executed, time taken, results returned, etc.
The main idea being that if I can do this, I shouldn't have to change any of my existing code and that I should be able to just intercept/wrap the ADO.Net calls... Is this possible?

You can globally intercept any methods that you have access to (ie: your generated models & context). If you're needing to intercept methods in framework BCL then no.
If you just want to get the SQL generated from your EF models then intercept one of the desired methods with the OnMethodBoundaryAspect and you can do your logging in the OnEntry and OnExit methods.
Remember, you can intercept only code you have access to. Generated EF code is accessable but will over write any changes you make to it so you will need to apply the aspect using either a partial class or with an assembly declaration. I would suggest the latter since you want global interception.
Just my 2 cents: You might want to look at other alternatives for this such as SQL profiler or redesigning your architecture.

Afterthought is an open source tool that supports modifying an existing dll without requiring you to recompile from source to add aspect attributes. For this to work, you would need to create amendments (the way you describe your changes in Afterthought) in a separate dll, and this dll would need to have an assembly-level attribute implementing IAmendmentAttribute that would identify the types in your target assembly to process.
Take a look at the logging example to see how this works and let me know if you have any questions/issues.
Please note that Afterthought modifies your target assembly to make calls to static methods in another assembly (your tool). If you want to intercept calls with modifying the target assembly in any way, then I recommending looking into the .NET profiling API.
Jamie Thomas (primary author of Afterthought)

Related

Use PostSharp to Generate a Type

We are currently using PostSharp for its standard functionality (logging, caching, transactions, and so on).
We also generate dynamically, at runtime, some custom classes, using Reflection.Emit. This obviously slows startup, and as we need to add more dynamic type generation, I am wondering, since all the information for the dynamic types is known at build time, whether we can use PostSharp to do this.
So, the question itself is, can I use PostSharp to achieve what I can do with Reflection.Emit, but at build time?
Regards
The PostSharp itself is using PostSharp.Sdk to manipulate the binary code, but this API is not publicly documented and supported at the moment. So, it's not future-proof to rely on it in your project.
The closest you can get with the documented API is probably by introducing interfaces, methods and properties: http://doc.postsharp.net/content/code-injections

How to implement DbContext hierarchy

What I'd LIKE to do is manipulate EF to support plugins that access a shared database. So the database would contain all of the tables for the main application plus all of the tables required for each plugin. As the application doesn't know anything about the plugin data structures, it cannot be responsible for their management. The plugins are solely responsible, and create the tables themselves. However, the plugins know about the host application and its data structures, so ideally should be able to reference them and even inherit from them, resulting in a database that is extensible yet able to implement optimized patterns.
In EF, this translates to a HostContext that contains the DbSets appropriate for the Host. Each Plugin, I thought, should have a PluginContext that inherits from HostContext that contains the DbSets needed by the plugin. The entity classes included in PluginContext would then be able to reference HostContext entities, and/or inherit from those entities, and EF would be able to resolve the table mapping and relationships.
I'm using EF6. When I attempt the above and try to list the single entity I've included in the PluginContext, an exception is thrown complaining that the entity doesn't exist. Sure enough, no matching table has been created.
Is what I'm attempting to do supported by EF? If so, what am I doing wrong?
As I mentioned here: EF6 Empty Model target string
I began this effort using Rowan Miller's example here: http://romiller.com/2013/02/15/extending-and-customizing-code-first-models-part-2-of-2/
In the end, I abandoned that approach, for a few reasons: 1) I couldn't get it to work (I can't remember exactly why but I do suspect it was related to differences in EF since the article was written), and 2) I didn't like the need to write manual migrations.
I ended up with PluginContexts that inherit from HostContext, as I had hoped, and am able to reference and even inherit from host entities. This has restrictions in its use though:
My plugin logic is completely self contained. I have no need for the host application to manipulate or create plugin entities. Therefore, I am not trying to get the system to subsitute any plugin entities for host entities. If construction of a particular entity subclass is required, then a plugin method must be provided for that and an inheritence hiearchy will be utilized.
Migrations can be built even on the plugin context as per normal. However, that migration may easily include migration code from the Host Context. So I have to remember to look for and remove these instructions. This is typically very straightforward and I believe is much less effort than building the equivalent from scratch.
If there is any change to the Host Context then this must be reflected in every Plugin Context. Basically, this means anytime a new migration is created to reflect changes in Host Context, migrations must be created for each plugin as well, even though that migration may be empty (it isn't really - the critical part here is updating the Model in the latest MigrationHistory record to reflect the Plugin model that has been changed because of the inherited Host model).
This approach is being used to extend an in-house application with in-house plugins, and so may not be as easy to adopt in other scenarios which Rowan's solution is probably better suited.

EntityFramework - Use Entities in Modules without access to the Database

I'm currently creating an application which is highly modular (using the Prism-Framework) and accesses a database via the EntityFramework implemented in CodeFirst.
My goal is to seperate the actual writing of the data into the Database from the "normal" use of the created Entities. Writing to the Database shall only be done by the main-Application but the Modules should still be able to use the Entity-Classes.
Thus, they must know the DataContext or at least the Entiy Classes. Here is the problem, though: If a module changes a property of an Entity Class and the main-Application calls "SaveChanges()" on the DataContext for some other reason, the changes made by the module are automatically saved to the Database without the main-Application having control over it.
How can I prevent this behaviour? The Modules must not be able to change the Database-Content, except via a defined Interface to the main-Application.
My first thought was to implement ICloneable in every entity-Class and to only pass clones of the Entity-Objects to the Modules to work with. The modules would then, if they wanted to request a change in the database, pass the cloned Objects to the main-Application which updates the original object and calls "SaveChanges()" on the DataContext.
Do you guys think this is a viable solution, or might there be a better way to implement this behaviour?
Thanks in advance!
Use the DbSet.AsNoTracking() Method to enable reading data from the database that will not be tracked by the DbContext.

Is It Possible To Setup An Interface Library For A DAL Using Entity Framework?

I have a model library (namespace Test.App.Model.EF) with the Entity Framework implementation in it. This has all of the entities provided in the EF designer for me which I want to use. Within this Model.EF implementation, I have several repository classes. I want to create interfaces for these classes and place them in a seperate interface library (Test.App.Model.Interface). So I do so, obviously the implementation library needs a reference the interfaces. BUT, I notice that the interfaces need to know about the objects in the EF designer (since I want to reuse them). I can't create a reference from the interface library to the ef implementation because then I'll have a circular reference.
So, as I write this, I'm coming to the conclusion that I'll probably need a Test.App.Entities.EF that has the Entity Framework "created" entities. That way my interfaces lib could reference without having to know about the Model.EF.
Does that sound like the way to go?
Ok, so after much wrestling with this, I found the buzz term that describes the situation. What I'm looking for here is called "Persistence Ignorance". This is what would make what I described in my thread happen. Well the Entity Framework that we use (not 4.0) does not support this yet (unless you go homegrown like done here).
With having that said, EF 4.0 will have this feature but from what I understand, it's coupled with .NET 4.0 (why it's called EF 4.0 in the first place) and that's not going on our production servers anytime soon. Since we've decided to go with this technology, our repository abstraction to interfaces will be placed on hold until upgrading to 4.0 is a viable option.
Let this be a caveat for those seeking the same information. Please also let me know if this sounds incorrect (because I would love to make this happen sooner then later but I don't want my team jumping through hoops when a later implementation will remedy the issue). Thanks all!

Extending Entity Framework

I'm developing a program which allows users to input some information which then gets stored and dynamically creates an image based on it.
I was going to use the Entity Framework to do the work with the data, but then I obviously need a way to generate the image. My thinking was that the "correct" way to do this was to somehow extend the data entity to include a function call like "CreateImage", or alternatively, to create a separate class not in the EF called "DataImage" which would have a "generate" method.
Extending the EF seems the "pure" way to do this, but I'm not sure how or if it's more practical than using the separate class.
Any thoughts on the best way to do this and how to do it using EF?
Putting this functionality in the EF would be a major violation of SRP. Breaking SRP has cascading negative effects as your application grows.
The approach you most likely want to take instead is a totally separate, encapsulated image generation service which takes interfaces that your EF entities implement. This decouples your image service from your data access completely; you get complete testability and zero dependencies right away.