Here is some code:
class Program
{
static void Main(string[] args)
{
MyClass class1 = new MyClass();
MyOtherClass class2 = new MyOtherClass();
Helper.UseAttribute<MyClass>(class1);
//Raise a warning to tell the developer that they cannot use this class
//as there is no property with the specified attribute.
Helper.UseAttribute<MyOtherClass>(class2);
}
}
public class MyAttribute : System.Attribute { }
class MyClass
{
[MyAttribute]
public string SomethingAwesome { get; set; }
}
class MyOtherClass
{
public string SomethingElseWhichIsAlsoPrettyAwesome { get; set; }
}
static class Helper
{
public static void UseAttribute<T>(T sender)
{
//Do something with the property that has MyAttribute
//If there isn't a property with this attribute, then raise
//a warning.
}
}
In an ideal scenario, I want to restrict a developer from passing classes to a method which do not have a certain attribute.
I am aware that I can use an interface, or a base class of some description, however the question really is whether something like the example above is possible.
If you're happy to either use the VS 2015 preview or wait until VS 2015 is out, you can use Roslyn for this.
You'd write a DiagnosticAnalyzer class, probably registering a syntax node analyzer to specifically look for invocations of Helper.UseAttribute<T>. When you find such a use, you'd find the symbol for T and check whether there are any properties with the MyAttribute attribute applied to it, and raise a warning if not. This warning will be shown in Visual Studio itself, as well as applying on CI builds (assuming you register the analyzer assembly appropriately).
It takes a while to get started with the Roslyn diagnostic APIs, but once you're used to it, it's really powerful.
Of course, another option is to throw an exception at execution time, and rely on there being unit tests around all callers so that you'd be able to catch it when they fail :) You should probably do that as well as adding compile-time support via Roslyn.
Best you can do right now is to handle it on runtime (and throw an exception or something). On design-/compiletime I think there is no possibility yet.
public static void UseAttribute<T>(T sender)
{
var hasAttribute = typeof(T).GetProperties().Any(prop => Attribute.IsDefined(prop, typeof(MyAttribute)));
if (!hasAttribute)
throw new Exception("Does not contain attribute");
}
Related
I am trying to setup a method that retrieves data from a database, and based on data in there it will create and hydrate a class with a generic component.
public class MyObject<T> where T : BaseMyType
{
T MyTypedObject { get; set; }
}
public class MyType1 : BaseMyType
{
string Key { get; set; }
}
public class MyType2 : BaseMyType
{
Guid Id { get; set; }
}
public MyObject<T> MyMethod<T>() where T : BaseMyType
{
if(Situation1)
return new MyObject(MyType1);
else
return new MyObject(MyType2);
}
This code complains that MyObject<MyType1> cannot be converted to MyObject<T>. Now I need to use it like this:
var myObject = MyMethod();
The call of course complains it cannot infer the type from the usage. I understand the compiler error messages, I just am not sure how to do what I need.
It can't be done, but…let's suppose for a moment that we could figure out a way for the following statement to compile in the way that you want:
var myObject = MyMethod();
Then what is the code using myObject going to look like? In this hypothetical scenario, the variable myObject will sometimes have the type MyType1 and sometime have the type MyType2. Will the code using myObject care about that?
If all that code will do is use members of the shared base type (i.e. BaseMyType), then the fix is easy. Just forget about the generic approach:
public BaseMyType MyMethod()
{
if(Situation1)
return new MyType1();
else
return new MyType2();
}
If it does care about the differences (i.e. needs to access either Key or Id depending on the type that was returned), then even if you could do the impossible, the calling code is still going to need to conditionally handle the individual scenarios based on the Situation1 variable. Which would mean that you put the check for Situation1 in the wrong place.
Instead, your caller should look more like this:
if (Situation1)
{
MyType1 myObject = MyMethod1();
// do situation 1 stuff
}
else
{
MyType2 myObject = MyMethod2();
// do situation 2 stuff
}
Where the implementation of your original MyMethod() has been split into two methods, MyMethod1() and MyMethod2(), corresponding to the two scenarios. Again, note the complete lack of generics as part of the implementation. It's not called for, and won't work.
It's even possible that you need a polymorphic implementation of the caller, i.e. so you don't have to check Situation1 more than once. But without a good, minimal, complete code example it would be impossible to comment more thoroughly on that possibility.
I have a class with a member that I need to keep for legacy code and I need to mark it as obsolete so that new code doesn't use it (without getting a warning).
Let's say the class looks like this:
class MyClass
{
[Obsolete]
private string _old = "...";
[Obsolete]
public string Old
{
get { return _old; }
}
}
I'm declaring that the member field _old is obsolete to make sure that new code inside the class do not use that field.
I'm also declaring that the property Old is obsolete to make sure that code outside of the class do not use the property.
When I compile this I get a warning in the property getter saying that _old is obsolete. I thought that the compiler would silently ignore this since the property itself is obsolete.
Am I missing something or do I need to add #pragma warning disable/restore for obsolete member fields everywhere they're used (even though the method/property itself is marked as obsolete)?
The reason that "I thought that the compiler would silently ignore this" is because it seems to do so for obsolete classes:
[Obsolete]
public class MyObsoleteClass
{
public string DoSomething()
{
// No warning here, since the class itself is obsolete
return new MyClass().Old;
}
}
As #Heinzi answered: this seems to be due to a bug in Visual Studio. I've filed a report on connect:
https://connect.microsoft.com/VisualStudio/feedback/details/1146809
It turns out that the bug in Visual Studio is not just limited to accessing an obsolete field from a property.
Accessing an obsolete property from an obsolete method should not yield a warning:
public class Class2
{
[Obsolete]
public string Property { get; set; }
[Obsolete]
public void Method()
{
this.Property = "value"; // <-- Incorrect warning reported
}
}
Neither should doing so from another class:
public class Class3
{
[Obsolete]
public string Property { get; set; }
}
public class Class4
{
[Obsolete]
public string Method()
{
return new Class3().Property; // <-- Incorrect warning reported
}
}
Interestingly, it works in the following class and when adding this class the other warnings (from Class4 and Class2) will magically disappear.
public class Class5
{
[Obsolete]
public void Method()
{
// No warning reported here, which is good.
// This magically makes the other warnings disappear too!
new Class2().Method();
}
}
Your code is fine, and your understanding of how the Obsolete attribute should work is correct: If you look at the "Output" tab after compilation, you will note that the compiler does not output a warning for your case (but will output a warning if you remove the Obsolete attribute from your property, as expected).
You are right, though, that Visual Studio sometimes displays a warning after making arbitrary changes to the code. This seems to be a bug in Visual Studio. If you can still reproduce it with the most current version, I would suggest that you file a bug report on http://connect.microsoft.com.
This would be a clever feature, but I don't see any indication in the documentation that it should work this way. On the other hand I would not use the Obsolate attribute on a private member (if the class is not extremly huge), but I would refactor it instead. I your case I would write this:
class MyClass
{
[Obsolete]
public string Old
{
get; private set;
}
}
And then you only need to change the usages of _old to Old and the problem is solved.
I have a class, where I use the singleton-pattern. The class looks like
public class MessageAccess
{
private static MessageAccess instance;
public static MessageAccess Instance
{
get { return instance ?? (instance = new MessageAccess()); }
}
private MessageAccess()
{
}
public void Initialize(string data)
{
//...
isInitialized = true;
}
private bool isInitialized;
public void ReadData1()
{
// This Method can always be called
}
public void ReadData2()
{
// This Method can only be called, if Initialize was called. Otherwise an exception will be thrown
}
}
Is it possible to generate a compiler-warning if the Method Initialize is never called
While I understand your point of view, I don't think such warning would be as handy as you think. I'm afraid .NET framework doesn't cater for this type of warnings for a couple of well defined reasons (please refer to this link: http://blogs.msdn.com/b/csharpfaq/archive/2004/03/19/why-doesn-t-c-warn-about-unused-methods.aspx).
One might think that the lack of this feature is a missed opportunity, but it's not quite the case. Your class, MessageAccess, is public and will be compiled into (let's say) a dll. Even if you had this warning while compiling your dll, you wouldn't want it to appear while compiling some external code using that dll's Initialize method (which is also public). You basically can't guarantee that no other code will ever use that method, and this is one of the better reasons not to have this warning.
If the class is not used from outside the assembly, you can make it internal. In this case, Code Analysis will generate a warning "Avoid uncalled private code", if the method is not called.
Is it possible to skip all tests from a specific class like in NUnit
[TestFixture]
[Ignore("Reason")]
public class TestClass {
}
No - there is no such facility at present, and the last time it was requested it was considered too low value to add,
One quick way of achieving the effect in xUnit is to comment out the public - private classes are not reflected over (obviously it won't appear on the skip list that way though).
UPDATE: Another way is to put a TraitAttribute on the class and then (assuming you're using the xunit.console runner) filter it out by running with /-trait traitName. (e.g. you can achieve ExplicitAttribute, some aspects of the BDD frameworky technique of Pending tests and similar semantics that way - of course the big problem is they don't show up in any reports when using any of these filtering techniques)
UPDATE 2: You can do
const string skip = "Class X disabled";
[Fact(Skip=skip)]
void Test() {}
Then you can change to to const string skip = null to undo the skip. The (dis)advantage of this is that the test is still shown as a Skipped test in the test list, generally with a reason included in the test run report (vs making it private which makes it likely to be forgotten)
Here is my hack to avoid error xUnit1000: Test classes must be public (checked on single Fact, I think Theories can be hacked this way, too).
// Uncomment to enable tests
//public class FactSwitch : FactAttribute { } // public! ahh, a bug!
// Uncomment to disable tests
internal class FactSwitch : Attribute { }
public class MyTests
{
[FactSwitch]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
(3 years later)
While searching for the same solution I found there are better ways to do the same.
Let's rewrite the example above in a way Ruben Bartelink suggested (continuation of his idea).
public class MyTests
{
//const string SkipOrNot = null; // Run all tests
const string SkipOrNot = "reason"; // Skip all tests
[Fact(Skip = SkipOrNot)]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
Nathan Cooper suggested a good improvement for my idea:
public class MyTests
{
// Uncomment to disable tests
//private class FactAttribute : Attribute { }
[Fact]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
So I like both ideas from Ruben and Nathan. There is a subtle difference between using Skip="something" (Ruben) and not using Skip at all. Using "Skip" will put all your tests in a "Skipped tests" warning zone, while "FactAttribute : Attribute" will hide them.
I've found yet another way of temporary disabling entire class without compiler warning.
Disabled:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
/*
public /**/class DatabaseTests
{
}
to enable move the /* one line up (i.e. using alt+up):
/*
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
public /**/class DatabaseTests
{
}
Note that using full namespace path for SupressMessage does not mess up with your usings.
You need to set the your class access level as as internal and surpress message as #Miq did:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]
internal class MyClassThatIsNotATestClass
{ ... }
You can create LocalOnlyFactAttribute
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => base.Skip = value; }
}
As far as I know, the simplest way to dynamically skip a whole xUnit test class at runtime is to use the TestFrameworkAttribute at the assembly level, to point to a class that implements the ITestFramework interface (or inherits from XunitTestFramework, which is simpler) and which overrides the CreateDiscoverer() method to return another class, that implements the ITestFrameworkDiscoverer interface (or inherits from XunitTestFrameworkDiscoverer, which is simpler), where you can finally override the IsValidTestClass() method, to decide whether a class should be skipped or not.
Here is some sample code:
[assembly: TestFramework("MyNamespace.Xunit.MyTestFramework", "MyAssembly")]
namespace MyNamespace.Xunit
{
public class MyTestFramework : XunitTestFramework
{
public MyTestFramework(IMessageSink messageSink)
: base(messageSink)
{
}
protected override ITestFrameworkDiscoverer CreateDiscoverer(
IAssemblyInfo assemblyInfo)
=> new MyTestFrameworkDiscoverer(
assemblyInfo,
SourceInformationProvider,
DiagnosticMessageSink);
}
public class MyTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer
{
public MyTestFrameworkDiscoverer(
IAssemblyInfo assemblyInfo,
ISourceInformationProvider sourceProvider,
IMessageSink diagnosticMessageSink,
IXunitTestCollectionFactory collectionFactory = null)
: base(
assemblyInfo,
sourceProvider,
diagnosticMessageSink,
collectionFactory)
{
}
protected override bool IsValidTestClass(ITypeInfo type)
=> base.IsValidTestClass(type) &&
FilterType(type);
protected virtual bool FilterType(ITypeInfo type)
{
// Insert your custom filter conditions here.
return true;
}
}
}
Tested with xUnit 2.4.1.
We are using it in Pomelo.EntityFrameworkCore.MySql (see AssemblyInfo.cs and MySqlXunitTestFrameworkDiscoverer.cs) (a bit more complex than the sample code here).
You could achieve this through a custom ITestClassCommand.
See http://mariangemarcano.blogspot.be/2010/12/xunitnet-running-tests-testcategory.html
Here's another hack that requires minimal changes to code
using FactAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
using TheoryAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
Any compatible attribute can be used for the replacement.
If you also use the InlineDataAttribute then you'll need to define a replacement as I don't think there's an existing compatible attribute.
using InlineDataAttribute = DummyDataAttribute;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class DummyDataAttribute : Attribute
{
public DummyDataAttribute(params object[] data)
{
}
}
Adding a reason almost after one year after the initial question. I have a set of tests which are calling real server apis, and I would like to run then on demand. With nUnit, it has Ignore attribute : with that set, test runner will skip those tests, but I can still manually run it.
xUnit has no such feature. The nearest one is setting such a class level attribute, and comment it out when I want to run it.
Consider creating LocalOnlyFactAttribute, which can be reused across multiple test files.
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => this.Skip = value; }
}
I am unexperienced with Aspect-Oriented Programming. However, I've read a fair amount of PDFs and documentation available from PostSharp, and I think that I understand the gist of the paradigm. I have a pretty unique problem, and I believe AOP can be used to solve it. My predicament is as follows:
Many classes will inherit from A, which can be enabled or disabled. Consider B, which extends A. If B is disabled, I would like all method execution and property and variable access/modification to be disabled. That is, B.ExecuteMethod(); and B.Property = newValue; will have no effect if B is disabled. Furthermore, if one expects a return value, the value will be defaulted to 0 or null if B is disabled. That is, I would like to have expected default values for objects and values.
I am using the PostSharp C# library, which seems very powerful and well-developed. I believe my problem can be solved by means of AttributeInheritance. For example, A can be defined as:
[ModularAttribute(AttributeInheritance = MulticastInheritance.Multicast)]
public class A {
private bool m_enabled;
public A(){
m_enabled = true;
}
public bool Enabled() {
get {
return m_enabled;
}
set {
m_enabled = value;
}
}
}
and B can extend A. Moreover, my attribute, ModularAttribute can be defined as:
[Serializable]
public sealed class ModularAttribute : OnMethodBoundaryAspect {
public ModularAttribute() {
}
public override void OnEntry(MethodExecutionArgs args) {
// only execute code if enabled
}
}
This attribute will be applied to B because B extends A.
The root of my problem is: I need ModularAttribute to reference A's Enabled property, such that OnEntry will only execute code if Enabled is true. Since this is a class-level aspect, I cannot parameterize a wrapped version of m_enabled to ModularAttribute since it is out of scope.
Is there a way that I can tell ModularAttribute that all of its owners will implement a specific interface? If so, could ModularAttribute access the specific properties from said interface? If so, this would solve my problem.
To clarify, I would like to "tell" PostSharp: "The class that uses ModularAttribute is guaranteed to implement C. So, let ModularAttribute access whatever C defines because it's ensured to work."
C can be defined as:
public interface C {
public bool Enabled();
}
Thus, in ModularAttribute, I could do something along the lines of
if (attachedClass.Enabled == false) {
// don't execute code
} else {
// execute code
}
This problem can be perceived as authentication on the per-object level rather than the more typical per-user level. Having to add an if, else check on every Property and Method that extends A seems like a cross-cutting concern. Thus, I think AOP is a fitting choice for this problem; however, because of my inexperience with this paradigm, I might be approaching it the wrong way.
Any guidance would be much appreciated. Thanks for the help,
I'm a little concerned that this much inheritance could be a design flaw or at least a huge maintenance headache, but assuming that it's not, let's soldier on...
I don't think there's a way to do exactly what you want to do. Even if PostSharp had the ability, C# needs to know the type at compile time (before PostSharp even touches it).
I suggest that you use CompileTimeValidate to verify that the class the aspect is used on is of a certain type, and once that's in place, you can cast args.Instance to your interface type without worrying about an invalid cast exception. And if that class doesn't implement IEnabled, then you'll get a compile-time error.
Here's a quick example:
public interface IEnabled
{
bool Enabled { get; }
}
[Serializable]
public class ModularAttribute : OnMethodBoundaryAspect
{
public override bool CompileTimeValidate(System.Reflection.MethodBase method)
{
if(typeof(IEnabled).IsAssignableFrom(method.DeclaringType))
return true;
Message.Write(method, SeverityType.Error, "MYERR001", "Aspect can't be used on a class that doesn't implement IEnabled");
return false;
}
public override void OnEntry(MethodExecutionArgs args)
{
var obj = (IEnabled) args.Instance; // this will always be a safe cast
if(!obj.Enabled)
args.FlowBehavior = FlowBehavior.Return;
}
}
There's a catch though: you don't want this aspect being used on the Enabled property itself, because that would cause a stack overflow (i.e. the aspect checks the property, causing the aspect to check the property, etc). So make sure to exclude Enabled using AttributeExclude.
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Enabled = false;
b.SomeMethod();
b.AnotherMethod();
}
}
public interface IEnabled
{
bool Enabled { get; }
}
[Modular(AttributeInheritance = MulticastInheritance.Multicast)]
public class A : IEnabled
{
[Modular(AttributeExclude = true)]
public bool Enabled { get; set; }
public void SomeMethod()
{
Console.WriteLine("in SomeMethod");
}
}
public class B : A
{
public void AnotherMethod()
{
Console.WriteLine("in AnotherMethod");
}
}