Using HandlerAttribute in clients without referencing Unity but using own framework - c#

We are building a framework that makes use of PolicyInjection to perform certain tasks. We make use of attributes for this. This code is written in a seperate framework solution.
Out CallHandler could look as follows:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method)]
public class MyCallHandlerAttribute : HandlerAttribute
{
...
}
And in Unity we have:
namespace Microsoft.Practices.Unity.InterceptionExtension
{
public abstract class HandlerAttribute : Attribute
{
...
}
}
In the client solution we have a call handler (MyCallHandler) that we register using Unity. To execute the code in the call handler we need to add the attribute above the class/method/property of the model:
[MyCallHandler(params[])]
public class MyModel : IMyModel
{
...
}
The problem now is that to use MyCallHandler we need a reference to the PolicyInjection DLL for the compiler to understand that a HandlerAttribute is an Attribute. If there is no reference we get a 'MyCallHandler' is not an attribute class warning (error when compiling).
How can we implement this in such a way without needing to reference the Unity DLL in our client solution(s), but only our framework DLLs?

Ok. So after some research and finding similar, but much simpler examples, I've come to the conclusion that this is not feasible unless you include a large (if not all) the Unity code in your project.
What I did try is to create my own policy injection behavior that looks only for MyCallHandler attributes rather than any HandlerAttribute. This means that I can let MyCallHandlerAttribute implement Attribute instead of HandlerAttribute. So MyModel knows that MyCallHandlerAttribute is an attribute.
This worked like a charm, but the problem now was that MyModel has no idea what ICallHandler is. Again, this is a Unity defined interface. This is likely to continue for several other things (IUnityContainer and whatnot).
I can provide code examples of what I did if anyone is interested.

Related

Prevent dependencies being required by other projects

I am writing a project which will encapsulate multiple Calendar APIs (Google Calendar, Outlook ect) in one service. This will allow me to integrate different APIs which can be mapped to our domain model. However I am having issues with required dependencies spilling over into other projects. Here's an example:
I have created a generic class which does most of the work and conversions from the API model to our model. Here's an example:
public abstract class CalendarAPIBase<TEventType> : ICalendarAPI
{
public CalendarEvent Get(string id)
{
if (string.IsNullOrEmpty(id))
throw new ArgumentNullException("id");
return Convert(GetEvent(id));
}
public List<CalendarEvent> GetAll()
{
List<CalendarEvent> result = new List<CalendarEvent>();
List<TEventType> es = GetAllEvents();
foreach (TEventType e in es)
result.Add(Convert(e));
return result;
}
protected abstract List<TEventType> GetAllEvents();
protected abstract CalendarEvent Convert(TEventType obj);
//More stuff below.
}
So this is a beautiful thing, anything that inherits CalendarAPIBase doesn't have to do much work other than getting the data from the API, the base class will handle the conversions.
Ok, so here's where things go wrong. I have created a GoogleCalendarAPI class, which inherits from CalendarAPIBase. It passes in the Event class, which belongs to a NuGet package Google.Apis.Calendar.v3.
public class GoogleCalendarAPI : CalendarAPIBase<Event>
The problem here is that this class is exposing the Event class, therefore anything that references this project will also need to reference Google.Apis.Calendar.v3. Ideally anyone wishing to use this service will only have to reference just the project and not have to worry about installing other NuGet packages.
How can I restructure my classes to prevent this from happening?
The most straightforward way to resolve this stuff is an Abstract factory pattern.
First, you make CalendarAPIBase<TEventType> and all its descendants internal. All the public stuff has to be concentrated within a public ICalendarAPI interface.
Next step is introducing public classes like this:
public static class GoogleCalendarAPIFactory
{
public static ICalendarAPI Instantiate( ....... )
{
.......
return new GoogleCalendarAPI( ..... );
}
}
The factory will make all the TEventType hassle hidden ftom the library user, therefore he will not need to add all the packages containing TEventType implementations.
I'm not sure if you can avoid referencing 3rd party assemblies if you use classes like Google.Apis.Calendar.v3.Event directly in your code.
However, you can use ILMerge to merge 3rd party API into your own, that way the dependencies of your assemblies will be deployed along with your assemblies.
I usually use ILMerge in the post build event.
For example:
After GoogleCalendarAPI project is built, merge GoogleCalendarAPI.dll and Google.Apis.Calendar.v3.dll and save it in "GoogleCalendarAPI_location\mergerd\GoogleCalendarAPI.dll"
Copy "GoogleCalendarAPI_location\mergerd\GoogleCalendarAPI.dll" to the location of the original GoogleCalendarAPI.dll and replace it.
Now you've got GoogleCalendarAPI.dll with Google.Apis.Calendar.v3 baked into it.
Now every assembly that references GoogleCalendarAPI.dll gets both.

Wrapping method call with PostSharp

Is there any way to wrap a method call with PostSharp? I have to add code around/outside a specific call.
The OnMethodBound add the code inside the specified method and the MethodInterception aspect redirects the call to the aspect, but I have to to add code outside the call.
Example:
Without aspect:
...
call();
...
With aspect:
beforePart();
call();
afterPart();
Currently, the only scenario in which PostSharp weaves the aspect around the call site is when you apply that aspect to a method in the referenced assembly.
When applying an aspect in your project, you can set the name of the external assembly in the AttributeTargetAssemblies property.
[Log(AttributeTargetAssemblies = "SomeLibrary", ...)]
PostSharp, of course, will not modify the existing external assembly, instead it will weave the aspect in your project's assembly around the calls to the referenced assembly.
Applying the aspect to the calls of the methods from the same assembly is not currently supported. In most scenarios this is not required, or there should be a reasonable workaround.
Maybe we'll be able to solve this if you provide more details about your synchronized method and why it's not possible to use method interception.
Update.
The possible workaround is to introduce the synchronization locks using aspects. You can write a custom OnMethodBoundaryAspect or use SynchronizedAttribute from the Threading Pattern Library.
Then you can use Aspect Dependency or Aspect Priority to make sure that the measuring aspect is introduced before the threading aspect. This way the behavior will be the same as when introducing the measuring aspect around the call site.
[Serializable]
[AspectTypeDependency(AspectDependencyAction.Order,
AspectDependencyPosition.Before,
typeof(SynchronizedAttribute))]
public class MeasureTimeAttribute : OnMethodBoundaryAspect
{
// ...
}
I had similar requirement and I wrote a logging aspect for all database calls I make with external library which is Dapper. I created an aspect:
[MulticastAttributeUsage(MulticastTargets.Method)]
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public sealed class SqlLogger : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
// logging code goes here
base.OnInvoke(args);
}
}
And then I registered it on assembly level:
[assembly: SqlLogger(AttributeTargetAssemblies = "Dapper", AttributePriority = 1)]

AOP Pre-compile time weaving?

I have been playing along with AOP for years, but didnt become 100% satisfied with the solutions.
AOP Frameworks with runtime weaving, like Spring.AOP, cannot change the interface of a class.
With post compile time Frameworks like Postsharp (anyone knows someone else ?) you can.
Check this sample out, it adds INotifyPropertyChanged implementation to your class. -> http://www.postsharp.net/model/inotifypropertychanged
This AOP feature is really great, but you run in troubles very soon...
If you want to access the new Interface within the hosting assembly, you cannot compile,
because the interface is added AFTER compilation.
so you get a "PropertyChanged is not defined"-error.
So you have to ugly workaround this, by seperating the classes into another assembly, so you can use those AOP advantages.
I remember, i ran into the same "Post compile time"-troubles using a T4-Template that generates source code, based on the reflected infos of a assembly. OK so post compile time is sometimes too late...
What i am looking for is a solution, where the source code of the class is parsed via a visual studio user defined tool, und then generates the code in a C# file, in a partial class.
(so all AOP applied classes have to be partial)
So its kind of "Pre-Compile-Time AOP".
This should definitly be possible, and could be done via using NRefactory as Code Parser.
Furthermore, Visual Studio would like this much more, than a post-compile modification.
So this solution eliminates disadvantages of post compile time weavers.
but does not give you all the features of AOP. But together with an AOP-Framework, this should be awsome.
Does anyone know a framework like this, or a discussion ?!
what do you think ?
kind regards, thomas
since you and I have already been corresponding on using SNAP as a viable alternative, I thought I'd post a summary of our discussion here for the benefit of those who are looking for a similar solution.
In short, SNAP provides a runtime AOP framework that doesn't change your code in any way. There's no post-compile step, just runtime interception which is predictable and easy to use.
What your are looking for is pMixins. It's still in beta, but it does exactly what you are looking for: design-time weaving. AOP code is generated into a partial code-behind class so it's available at design-time.
So this means you can do this in one file and the compiler is happy, visual studio is happy, resharper is happy:
Define an interface:
public interface ISomeInterface
{
void SomeMethod();
}
Create an implementation of the interface (I call this a Mixin):
public class SomeInterfaceImplementation : ISomeInterface
{
public void SomeMethod()
{
//implementation
}
}
Define a Target file (which will consume the Mixin):
[pMixin(Mixin = typeof(SomeInterfaceImplementation))]
public partial class Target { }
Let's create a utility class that works with SomeInterface and SomeInterfaceImplementation:
public class Utility
{
public void DoSomeWorkOnSomeInterface(ISomeInterface obj)
{
obj.SomeMethod();
}
public void DoSomeWorkOnImplementation(SomeInterfaceImplementation obj)
{
obj.SomeMethod();
}
}
And now let's see it all work together:
class Program
{
private static void Main(string[] args)
{
//Call the mixed in method
new Target().SomeMethod();
//Target implements ISomeInterface is code-behind
new Utility().DoSomeWorkOnSomeInterface(new Target());
//Target has an implicit conversion operator to
//SomeInterfaceImplementation in code-behind
new Utility().DoSomeWorkOnImplementation(new Target());
}
}
The reason this works is because as soon as you save the file, the pMixins code generator immediately does design-time weaving and updates the code-behind file. It adds the SomeMethod directly to Target, updates Target's class definition to implement ISomeInterface and creates conversion operators.
Disclosure: I am on the pMixins development team.
In the case of PostSharp, you can access an interface introduced at post-compile-time by using the method Post.Cast, which is a kind of cast operator that is verified at post-compile-time. See http://doc.postsharp.net/postsharp-3.0/Content.aspx/PostSharp-3.0.chm/html/M_PostSharp_Post_Cast__2.htm for documentation.

Reusable Class Library Implementation

I've built a reusable Class Library to encapsulate my Authentication logic. I want to be able to reuse the compiled *.dll across multiple projects.
What I've got works. But, something about how I'm making the reference, or how my Class Library is structured isn't quite right. And I need your help to figure out what I'm doing-wrong/not-understanding...
I've got a Class Library (Authentication.dll) which is structured like this:
namespace AUTHENTICATION
{
public static class authentication
{
public static Boolean Authenticate(long UserID, long AppID) {...}
//...More Static Methods...//
}
}
In my dependent project I've added a reference to Authentication.dll, and I've added a using directive...
using AUTHENTICATION;
With this structure I can call my Authenticate method, from my dependent project, like so...
authentication.Authenticate(1,1)
I'd like to be able to not have to include that "authentication." before all calls to methods from this Class Library. Is that possible? If so, what changes do I need to make to my Class Library, or how I'm implementing it in my dependent project?
In C# a function cannot exist without a class. So you always need to define something for it, being a class for a static method or an object for an object method.
The only option to achieve that would be to declare a base class in the Authentication assembly from which you inherit in the dependent projects.
You could expose Authenticate as a protected method (or public works too), and call it without specifying the class name.
public class MyClassInDependentProject : authentication
{
public void DoSomething(int userId, long appId)
{
var success = Authenticate(userId, appId);
…
}
}
That said, you'll quickly find this to be a bad design. It conflates a cross-cutting concern with all sorts of other classes, and those classes are now precluded from inheriting from any other class.
Composition is a core principle of object-oriented programming, and we have the idiom "Favor composition over inheritance." This simply means that we break down complexity into manageable chunks (classes, which become instantiated as objects), and then compose those objects together to handle complex processing. So, you have encapsulated some aspect of authentication in your class, and you provide that to other classes compositionally so they can use it for authentication. Thinking about it as an object with which you can do something helps, conceptually.
As an analogy, think about needing to drill a hole in the top of your desk. You bring a drill (object) into your office (class). At that point, it wouldn't make sense to simply say "On," because "On" could be handled by your fan, your lamp, your PC, etc. (other objects in your class). You need to specify, "Drill On."
If you are making a class library in C# you should learn to use the naming conventions that exists: Design Guidelines for Developing Class Libraries
Here is how you should name namespaces: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
C# is also an object oriented language, hence the need of classes (using Authentication as you should name your class).
It also seems like the data source is hard coded. Your class library users (even if it's just you) might want to configure the data source.
Google about singleton and why it's considered to be an anti pattern today (in most cases).
You are obliged to use Class in order to invoke your method, just
When is static class just NameClass.Method
When is not static, you must create instance, ClassName ob = new ClassName(); ob.Method();
The format of a call like this is class.method, and you really can't escape using the "class" moniker even with the "using" designation. Something has to "host" the function.
I don't think what you are asking for is possible without using the base class method Jay mentioned. If all you want is to simplify the syntax whenever you call Authenticate() however, this silly solution (adding an extra method in each class that needs to do authentication) may be just what you want:
private static void DoAuth(long UserID, long AppID){
authentication.Authenticate(UserID, AppID)
}
If the ID's are always the same within some context, you could also overload it:
private static void DoAuth(){
DoAuth(1,1)
}
Yes, this does mean you have to add more code wherever you want to do the authentication (that's why it's silly! ;) ). It does also however, also reduce this:
authentication.Authenticate(1,1);
...into this:
DoAuth();
I leave the cost / benefit analysis of this up to you..
I know I am some 3 years late but here goes nothing.
To keep your code cleaner and more readable you should create a new namespace for all the re-usable code that you want to have. Then in that namespace have the Authentication Class and Authenticate Function.
To use this you can easily set a using on your namespace and use the function as you are doing like
Authentication.Authenticate()
But to use
Authenticate()
by itself you can always do
using MyNamespace.Authentication;
and in your code use Authenticate Function directly.

Using the generated .net classes to extend own classes. HowTo?

I used the OWLGrinder to create the assembly and imported the library into my project. That works fine. Now I want to write my own set of classes. Therefore I extended these with the equivalent of the assembly. But it just doesn't work.
The ontology holds a class named ManagementObject.
I created another Class (C#) called RealWorldObject:
public class RealWorldObject : ManagementObject
{
public RealWorldObject(string uri) : base(uri) { }
public RealWorldObject(string uri, RdfDocument rdfdocument) : base(uri, rdfdocument) { }
public RealWorldObject(RdfDocument rdfdocument) : base(rdfdocument) { }
public String getClassName()
{
return this.OwlClassName;
}
public static RdfDocument addRealWorldObjectIndividualt(RdfDocument rdfDocument)
{
Vehicle vehicle = new Vehicle("vehicle1", rdfDocument);
FixedEvent fxE1 = new FixedEvent("autoGekauft", rdfDocument);
fxE1.agent = new xmlns.com.foaf._01.Person("robert", rdfDocument);
vehicle.hasFixedEvent = fxE1;
return rdfDocument;
}
Which leads to the error:
ObjectManagement.Object.RealWorldObject does declare one (and only one) OwlClassAttribute. This is an implementation bug of the plugin.
How else should I extend the generated classes by the OWLGrinder.
Thx it is a long time ago that I used C#, so I'm kind of rusty.
The auto-generated classes produced by OwlGrinder.exe have not been designed for inheritance in mind. I am not saying it is wrong, it is just not designed for that. The auto-generated classes contain plenty of metadata defined as class attributes and inheritance hides all of that. The infrastructure counts on the presence of these attributes and if they are hidden, you get these runtime error messages.
Using Visual Studio Object Browser, take a look of the attributes over the auto-generated classes. OwlClassAttribute, SubClassOfAttribute, LightVersionAttribute are certainly mandatory. You may simply copy/paste the class attributes of ManagementObject on the top of your RealWorldObject class. I assume, it will work. But again, you might bump into additional show stoppers, as you do not follow the default routes ROWLEX has been designed for. This is a bit living on the edge :)
Instead of inheritance, you might consider reverse engineering your auto-generated assembly to C# using Reflector or other tools. Having the source code in your hand, you may modify the generated classes directly. You might make your ManagementObject class partial, and implement your additional methods in a separate file.

Categories