I have the following code:
public partial class AuditLog : IBusinessEntity
{
public BusinessEntityType EntityType { get { return BusinessEntityType.AuditLog; } }
/// <summary>
/// Constructor accepting parameter initialization arguments
/// </summary>
/// <param name="userName"></param>
/// <param name="entity"></param>
/// <param name="command"></param>
/// <param name="commandText"></param>
public AuditLog(string userName, BusinessEntityType entity, AuditLogCommand command, string commandText)
{
this.Timestamp = DateTime.Now;
this.UserName = userName;
this.Entity = entity.ToString();
this.Command = command.ToString();
this.CommandText = commandText;
}
}
This is generating a CA2214 warning. The BusinessEntityType and AuditLogCommand method parameters are both enumerations. I don't see what the issue is here, and therefore am not certain how to satisfy the warning.
Thanks.
Is one or more of your properties virtual ? Then that is why, since CA2214 is the "Do not call overridable methods in constructors" warning.
Here is the reasoning for the rule from MSDN:
When a virtual method is called, the
actual type that executes the method
is not selected until run time. When a
constructor calls a virtual method, it
is possible that the constructor for
the instance that invokes the method
has not executed.
What this means is that if someone inherits from your class, and overrides a method or property that is accessed in your constructor - then the overriding implementation will be hit before the constructor for the inherited class has run. This might lead to problems if the overriding implementation relies on state set in the constructor.
To satisfy the warning, you need to make the properties and methods accessed in the constructor non-virtual (you could make the type sealed, if appropiate).
Related
I'm using a Unity IoC container to do Dependency Injection. I designed my system around the idea that, at least for a single resolution, all types in the hierarchy would behave as singletons, that is, same type resolutions within that hierarchy would lead to the same instances.
However, I (a) would like to scan my assemblies to find types and (b) don't want to explicitly tell unity that every type is to be resolved as a singleton when registering types in the configuration file.
So, is there a way to tell unity to treat all registered mappings as singleton?
In case anyone is still looking for this... The following extension will change the default, while still allowing you to override with some other manager:
/// <summary>
/// This extension allows the changing of the default lifetime manager in unity.
/// </summary>
public class DefaultLifetimeManagerExtension<T> : UnityContainerExtension where T : LifetimeManager
{
/// <summary>
/// Handle the registering event
/// </summary>
protected override void Initialize()
{
Context.Registering += this.OnRegister;
}
/// <summary>
/// Remove the registering event
/// </summary>
public override void Remove()
{
Context.Registering -= this.OnRegister;
}
/// <summary>
/// Handle the registration event by checking for null registration
/// </summary>
private void OnRegister(object sender, RegisterEventArgs e)
{
if (e.LifetimeManager == null)
{
var lifetimeManager = (LifetimeManager)Activator.CreateInstance(typeof (T));
// Set this internal property using reflection
lifetimeManager
.GetType()
.GetProperty("InUse", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(lifetimeManager, true);
Context.Policies.Set<ILifetimePolicy>(lifetimeManager, new NamedTypeBuildKey(e.TypeTo, e.Name));
if (lifetimeManager is IDisposable)
{
Context.Lifetime.Add(lifetimeManager);
}
}
}
}
You could add a Unity extension at the 'Lifetime' stage of the resolution pipeline and in it always use a ContainerControlledLifetimeManager instance.
Edit: In fact this post has the exact example:
https://unity.codeplex.com/discussions/352179
Suppose I have this interface
public interface IFoo
{
///<summary>
/// Foo method
///</summary>
void Foo();
///<summary>
/// Bar method
///</summary>
void Bar();
///<summary>
/// Situation normal
///</summary>
void Snafu();
}
And this class
public class Foo : IFoo
{
public void Foo() { ... }
public void Bar() { ... }
public void Snafu() { ... }
}
Is there a way, or is there a tool that can let me automatically put in the comments of each member in a base class or interface?
Because I hate re-writing the same comments for each derived sub-class!
You can always use the <inheritdoc /> tag:
public class Foo : IFoo
{
/// <inheritdoc />
public void Foo() { ... }
/// <inheritdoc />
public void Bar() { ... }
/// <inheritdoc />
public void Snafu() { ... }
}
Using the cref attribute, you can even refer to an entirely different member in an entirely different class or namespace!
public class Foo
{
/// <inheritdoc cref="System.String.IndexOf" />
public void Bar() { ... } // this method will now have the documentation of System.String.IndexOf
}
Use /// <inheritdoc/> if you want inheritance. Avoid GhostDoc or anything like that.
I agree it is annoying that comments are not inherited. It would be a fairly simple add-in to create if someone had the time (i wish i did).
That said, in our code base we put XML comments on the interfaces only and add extra implementation comments to the class. This works for us as our classes are private/internal and only the interface is public. Any time we use the objects via the interfaces we have full comments display in intellisence.
GhostDoc is good start and has made the process easier to write comments. It is especially useful keeping comments up-to-date when you add/remove parameters, re-run GhostDoc and it will update the description.
GhostDoc does exactly that. For methods which aren't inherited, it tries to create a description out of the name.
FlingThing() becomes "Flings the Thing"
I would say to directly use the
/// <inheritdoc cref="YourClass.YourMethod"/> --> For methods inheritance
And
/// <inheritdoc cref="YourClass"/> --> For directly class inheritance
You have to put this comments just on the previous line of your class/method
This will get the info of your comments for example from an interface that you have documented like :
/// <summary>
/// This method is awesome!
/// </summary>
/// <param name="awesomeParam">The awesome parameter of the month!.</param>
/// <returns>A <see cref="AwesomeObject"/> that is also awesome...</returns>
AwesomeObject CreateAwesome(WhateverObject awesomeParam);
Java has this, and I use it all the time. Just do:
/**
* {#inheritDoc}
*/
And the Javadoc tool figures it out.
C# has similar marker:
<inheritDoc/>
You can read more here:
http://www.ewoodruff.us/shfbdocs/html/79897974-ffc9-4b84-91a5-e50c66a0221d.htm
Another way is to use the <see /> XML documentation tag.
This is some extra effort but works out of the box...
Here are some examples:
/// <summary>
/// Implementation of <see cref="IFoo"/>.
/// </summary>
public class Foo : IFoo
{
/// <summary>
/// See <see cref="IFoo"/>.
/// </summary>
public void Foo() { ... }
/// <summary>
/// See <see cref="IFoo.Bar"/>
/// </summary>
public void Bar() { ... }
/// <summary>
/// This implementation of <see cref="IFoo.Snafu"/> uses the a caching algorithm for performance optimization.
/// </summary>
public void Snafu() { ... }
}
Update:
I now prefer to use /// <inheritdoc/> which is now supported by ReSharper.
ReSharper has an option to copy the comments from the base class or interface.
I ended up creating a tool to post-process the XML documentation files to add support for replacing the <inheritdoc/> tag in the XML documentation files themselves. Available at www.inheritdoc.io (free version available).
Well, there is a kind of native solution, I found for .NET Core 2.2
The idea is to use <include> tag.
You can add <GenerateDocumentationFile>true</GenerateDocumentationFile> your .csproj a file.
You might have an interface:
namespace YourNamespace
{
/// <summary>
/// Represents interface for a type.
/// </summary>
public interface IType
{
/// <summary>
/// Executes an action in read access mode.
/// </summary>
void ExecuteAction();
}
}
And something that inherits from it:
using System;
namespace YourNamespace
{
/// <summary>
/// A type inherited from <see cref="IType"/> interface.
/// </summary>
public class InheritedType : IType
{
/// <include file='bin\Release\netstandard2.0\YourNamespace.xml' path='doc/members/member[#name="M:YourNamespace.IType.ExecuteAction()"]/*'/>
public void ExecuteAction() => Console.WriteLine("Action is executed.");
}
}
Ok, it is a bit scary, but it does add the expected elements to the YourNamespace.xml.
If you build Debug configuration, you can swap Release for Debug in the file attribute of include tag.
To find a correct member's name to reference just open generated Documentation.xml file.
I also assume that this approach requires a project or solution to be build at least twice (first time to create an initial XML file, and the second time to copy elements from it to itself).
The bright side is that Visual Studio validates copied elements, so it is much easier to keep documentation and code in sync with interface/base class, etc (for example names of arguments, names of type parameters, etc).
At my project, I have ended up with both <inheritdoc/> (for DocFX) and <include/> (For publishing NuGet packages and for validation at Visual Studio):
/// <inheritdoc />
/// <include file='bin\Release\netstandard2.0\Platform.Threading.xml' path='doc/members/member[#name="M:Platform.Threading.Synchronization.ISynchronization.ExecuteReadOperation(System.Action)"]/*'/>
public void ExecuteReadOperation(Action action) => action();
End the question:
This feature has been added at VS2019 v16.4.
https://developercommunity.visualstudio.com/t/608809#T-N875117
It works on the interfeace and abstruct class overrideable members
I'm using Ninject and AOP to do some caching. I have a Attribute that I can apply to any method in my repository and on BeforeInvoke it will return my cached Object if there is one and AfterInvoke create a cached object. This all works great but I can't figure out how to stop initial method from being called, ie if there is a cached object the return that instead of calling a the intyercepted method. My interceptor is here:
public class CacheInterceptor : SimpleInterceptor
{
protected override void BeforeInvoke(IInvocation invocation)
{
Type returnType = invocation.Request.Method.ReturnType;
string cacheKey = CacheKeyBuilder.GetCacheKey(invocation, serializer);
object cachedValue = cache.Get(cacheKey);
if (cachedValue == null)
{
invocation.Proceed();
}
else
{
object returnValue = serializer.Deserialize(returnType, cachedValue);
invocation.ReturnValue = returnValue;
returnedCachedResult = true;
}
}
}
Even though in the else statement I am clearly not saying to call the invoked Method 'invocation.Proceed();' it still invokes it. How do I tell ninject to just return with the invocation.ReturnValue ?
You can't use SimpleInterceptor in this case because that is meant as base class for the most common scenario where you want to do an action before or after the actual method call. Also you are not allowed to call Proceed Instead implement the IInterceptor interface and put your code into the Intercept method.
But probably we should extend SimpleInterceptor in a future version so that you can prevent that the actual method is called:
public abstract class SimpleInterceptor : IInterceptor
{
private bool proceedInvocation = true;
/// <summary>
/// Intercepts the specified invocation.
/// </summary>
/// <param name="invocation">The invocation to intercept.</param>
public void Intercept( IInvocation invocation )
{
BeforeInvoke( invocation );
if (proceedInvocation)
{
invocation.Proceed();
AfterInvoke( invocation );
}
}
/// <summary>
/// When called in BeforeInvoke then the invokation in not proceeded anymore.
/// Or in other words the decorated method and AfterInvoke won't be called anymore.
/// Make sure you have assigned the return value in case it is not void.
/// </summary>
protected void DontProceedInvokation()
{
this.proceedInvocation = false;
}
/// <summary>
/// Takes some action before the invocation proceeds.
/// </summary>
/// <param name="invocation">The invocation that is being intercepted.</param>
protected virtual void BeforeInvoke( IInvocation invocation )
{
}
/// <summary>
/// Takes some action after the invocation proceeds.
/// </summary>
/// <param name="invocation">The invocation that is being intercepted.</param>
protected virtual void AfterInvoke( IInvocation invocation )
{
}
}
I have a NativeActivity derived activity that I wrote that is to use bookmarks as a trigger for a pick branch. Using something I found on MSDN I tried writing this to trigger the branch. The branch contains activities that fire service callbacks to remote clients via send activities. If I set a delay for the trigger, callbacks fire to the clients successfully. If I use my code activity, the pick branch activities don't fire.
public sealed class UpdateListener : NativeActivity<ClientUpdate>
{
[RequiredArgument]
public InArgument<string> BookmarkName { get; set; }
protected override void Execute(NativeActivityContext context)
{
context.CreateBookmark(BookmarkName.Get(context),
new BookmarkCallback(this.OnResumeBookmark));
}
protected override bool CanInduceIdle
{
get { return true; }
}
public void OnResumeBookmark(NativeActivityContext context, Bookmark bookmark, object obj )
{
Result.Set(context, (ClientUpdate)obj);
}
}
So it takes an arg to set the bookmark name for future bookmark references to execute the trigger. OnResumeBoookmark() takes in a ClientUpdate object that is passed by my application that is hosting the workflowapp. The activity is to return the object so the ClientUpdate can be passed to the workflow and have it sent to the remote clients via the send activity in the pick branch. In theory anyways.
For some reason it seems to be correct but feels wrong. I'm not sure if I should write the Activity in a different way to take care of what I need for my WF service.
I think your intentions would be a bit clearer if you created an extension (that implements IWorkflowInstanceExtension) to perform your action here.
For example:
public sealed class AsyncWorkExtension
: IWorkflowInstanceExtension
{
// only one extension per workflow
private WorkflowInstanceProxy _proxy;
private Bookmark _lastBookmark;
/// <summary>
/// Request the extension does some work for an activity
/// during which the activity will idle the workflow
/// </summary>
/// <param name="toResumeMe"></param>
public void DoWork(Bookmark toResumeMe)
{
_lastBookmark = toResumeMe;
// imagine I kick off some async op here
// when complete system calls WorkCompleted below
// NOTE: you CANNOT block here or you block the WF!
}
/// <summary>
/// Called by the system when long-running work is complete
/// </summary>
/// <param name="result"></param>
internal void WorkCompleted(object result)
{
//NOT good practice! example only
//this leaks resources search APM for details
_proxy.BeginResumeBookmark(_lastBookmark, result, null, null);
}
/// <summary>
/// When implemented, returns any additional extensions
/// the implementing class requires.
/// </summary>
/// <returns>
/// A collection of additional workflow extensions.
/// </returns>
IEnumerable<object> IWorkflowInstanceExtension
.GetAdditionalExtensions()
{
return new object[0];
}
/// <summary>
/// Sets the specified target
/// <see cref="WorkflowInstanceProxy"/>.
/// </summary>
/// <param name="instance">The target workflow instance to set.</param>
void IWorkflowInstanceExtension
.SetInstance(WorkflowInstanceProxy instance)
{
_proxy = instance;
}
}
Within the Activity, you'd use this thusly:
var ext = context.GetExtension<AsyncWorkExtension>();
var bookmark = context.CreateBookmark(BookmarkCallback);
ext.DoWork(bookmark);
return;
This way is much more explicit (instead of using the bookmark name to convey meaning to the "outside" world) and is much easier to extend if, say, you require to send out more information than a bookmark name.
Is there something actually resuming the bookmark here? If not the workflow will wait very patiently and nothing will happen.
Ok,
this question is for people with either a deep knowledge of PRISM or some magic skills I just lack (yet). The Background is simple: Prism allows the declaration of events to which the user can subscribe or publish. In code this looks like this:
_eventAggregator.GetEvent<LayoutChangedEvent>().Subscribe(UpdateUi, true);
_eventAggregator.GetEvent<LayoutChangedEvent>().Publish("Some argument");
Now this is nice, especially because these events are strongly typed, and the declaration is a piece of cake:
public class LayoutChangedEvent : CompositePresentationEvent<string>
{
}
But now comes the hard part: I want to trace events in some way. I had the idea to subscribe using a lambda expression calling a simple log message. Worked perfectly in WPF, but in Silverlight there is some method access error (took me some time to figure out the reason).. If you want to see for yourself, try this in Silverlight:
eA.GetEvent<VideoStartedEvent>().Subscribe(obj => TraceEvent(obj, "vSe", log));
If this would be possible, I would be happy, because I could easily trace all events using a single line to subscribe. But it does not... The alternative approach is writing a different functions for each event, and assign this function to the events. Why different functions? Well, I need to know WHICH event was published. If I use the same function for two different events I only get the payload as argument. I have now way to figure out which event caused the tracing message.
I tried:
using Reflection to get the causing event (not working)
using a constructor in the event to enable each event to trace itself (not allowed)
Any other ideas?
Chris
PS: Writing this text took me most likely longer than writing 20 functions for my 20 events, but I refuse to give up :-) I just had the idea to use postsharp, that would most likely work (although I am not sure, perhaps I end up having only information about the base class).. Tricky and so unimportant topic...
Probably the easiest thing would be to subclass CompositePresentationEvent and override the behavior of the Publish event. Here's the source for CompositePresentationEvent:
http://compositewpf.codeplex.com/SourceControl/changeset/view/26112#496659
Here's the current Publish behavior:
public virtual void Publish(TPayload payload)
{
base.InternalPublish(payload);
}
So you could just add a little to this:
public virtual override void Publish(TPayload payload)
{
ILoggerFacade logger = ServiceLocator.Current.GetInstance<ILoggerFacade>();
logger.Log("Publishing " + payload.ToString(), Category.Debug, Priority.Low);
base.InternalPublish(payload);
}
Here I'm using the logger facility built into Prism, but feel free to substitute your own (or better, just implement ILoggerFacade!).
I was surprised that there were any default messages being published or places to plug in tracing in this system... as much as EventAggregator is abused by people, you'd think this would be a big request!
A little late but better late than never! I recently had the same problem and this is how I solved it.
First, I didn't like the Prism method of publishing/subscribing to events, so I used a method like this instead:
http://neverindoubtnet.blogspot.com/2009/07/simplify-prism-event-aggregator.html
This post above suggests using Extension methods on Event Aggregator to simplify the call to publish/subscribe. As a result your client code looks like this:
IEventAggregator ev;
ev.Publish<MyCustomMessage>();
//or
ev.Publish(new MyCustomMessage(someData));
//and similarly subscription
ev.Subscribe<MyCustomMessage(this.OnCustomMessageReceived);
// ...
private void OnCustomMessageReceived(MyCustomMessage message)
{
// ...
}
// With a BaseMessageEvent class as follows (see the blog post above for where this comes from)
/// <summary>
/// Base class for all messages (events)
/// </summary>
/// <typeparam name="TMessage">The message type (payload delivered to subscribers)</typeparam>
public class BaseEventMessage<TMessage> : CompositePresentationEvent<TMessage>
{
}
Ok this is great, but rather than hacky extension methods I implemented my own event service as follows:
/// <summary>
/// The EventService instance
/// </summary>
public class EventService : IEventService
{
private readonly IEventAggregator eventAggregator;
private readonly ILoggerFacade logger;
/// <summary>
/// Initializes a new instance of the <see cref="EventService"/> class.
/// </summary>
/// <param name="logger">The logger instance.</param>
/// <param name="eventAggregator">The event aggregator instance.</param>
public EventService(IEventAggregator eventAggregator, ILoggerFacade logger)
{
this.logger = logger;
this.eventAggregator = eventAggregator;
}
#region IEventService Members
/// <summary>
/// Publishes the event of type TMessageType to all subscribers
/// </summary>
/// <typeparam name="TMessageType">The message type (Payload), must inherit CompositeEvent</typeparam>
public void Publish<TMessageType>() where TMessageType : BaseEventMessage<TMessageType>, new()
{
TMessageType message = Activator.CreateInstance<TMessageType>();
this.Publish(message);
}
/// <summary>
/// Publishes the event of type TMessageType to all subscribers
/// </summary>
/// <typeparam name="TMessageType">The message type (Payload), must inherit CompositeEvent</typeparam>
/// <param name="message">The message to publish</param>
public void Publish<TMessageType>(TMessageType message) where TMessageType : BaseEventMessage<TMessageType>, new()
{
// Here we can log our message publications
if (this.logger != null)
{
// logger.log etc..
}
this.eventAggregator.GetEvent<TMessageType>().Publish(message);
}
/// <summary>
/// Subscribes to the event of type TMessage
/// </summary>
/// <typeparam name="TMessageType">The message type (Payload), must inherit CompositeEvent</typeparam>
/// <param name="action">The action to execute when the event is raised</param>
public void Subscribe<TMessageType>(Action<TMessageType> action) where TMessageType : BaseEventMessage<TMessageType>, new()
{
// Here we can log our message publications
if (this.logger != null)
{
// logger.log etc..
}
this.eventAggregator.GetEvent<TMessageType>().Subscribe(action);
}
#endregion
}
Then I register IEventService/EventService as a singleton in the bootstrapper and forget about using the IEventAggregator, just use this (however if someone uses the IEventAggregator, its the same instance as that used by the EventService so will still work).
Finally, another trick to add is to use the Stack Frame to tell me where publications and subscriptions are coming from. Note this is a slow process (unwinding the stack frame) so use it sparingly. If you are
raising an event regularly then perhaps put a flag in your BaseEventMessage and check that to see whether to log publications for certain event types.
// Inside Publish method ... Log the subscription
if (this.logger != null)
{
Type messageType = typeof(TMessageType);
Type callingType = GetCallingType();
string methodName = GetCallingMethod().Name;
// Log the publication of this event
this.logger.Log(
string.Format("Event {0} was published by {1}.{2}()",
messageType.Name,
callingType.Name,
methodName),
Category.Debug,
Priority.Low));
}
// Additional methods to add to EventService to get the calling type/class
//
/// <summary>
/// Gets the Type that called the method or property where GetCallingType is called
/// </summary>
/// <returns>The class type that called</returns>
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static Type GetCallingType()
{
int skip = 2;
MethodBase method = new StackFrame(skip, false).GetMethod();
return method.DeclaringType;
}
/// <summary>
/// Gets the Method that called the method or property where GetCallingMethod is called
/// </summary>
/// <returns>The method type that was called</returns>
public static MethodBase GetCallingMethod()
{
return new StackFrame(2, false).GetMethod();
}
Note the above won't work in Silverlight (the use of the StackFrame), but the rest does. I've found this invaluable when debugging the multitude of events flying around a Prism app!