How can I retrieve the 'AssemblyCompany' setting (in AssemblyInfo.cs)? [duplicate] - c#

This question already has answers here:
Retrieve AssemblyCompanyName from Class Library
(6 answers)
Closed 9 years ago.
Is it possible to retrieve this value at runtime?
I'd like to keep the value in one place, and retrieve it whenever my application needs to output the name of my company.

This should do it:
using System.Reflection;
string company = ((AssemblyCompanyAttribute)Attribute.GetCustomAttribute(
Assembly.GetExecutingAssembly(), typeof(AssemblyCompanyAttribute), false))
.Company;
If you really want to keep the value in one place and you have multiple assemblies in your solution, you could either:
Use GetEntryAssembly instead of GetExecutingAssembly and set the company attribute only on your entry assembly, or better:
Use a central assembly info file, see this answer
UPDATE
Improved the code by suggestion of #hmemcpy so it doesn't need [0] anymore. Thanks!

If you want a nice generic method for fetching the assembly Info data try the following:
public string GetAssemblyAttribute<T>(Func<T, string> value)
where T : Attribute
{
T attribute = (T)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof (T));
return value.Invoke(attribute);
}
So you can then call
string title = GetAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title);
string copyright = GetAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright);
string version = GetAssemblyAttribute<AssemblyVersionAttribute>(a => a.Version);
string description = GetAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description);

Building on Adam Price's very elegant method -- with the correct comments from Mark about it not working for Version... Came up with the following methods -- one for getting the current executing AssemblyInfo properties -- and one for getting the "calling" assembly's AssemblyInfo properties.
Have it up on my blog at http://lancelarsen.com/reading-values-from-assemblyinfo-cs/
/// <summary>
/// Gets the values from the AssemblyInfo.cs file for the current executing assembly
/// </summary>
/// <example>
/// string company = AssemblyInfo.Company;
/// string product = AssemblyInfo.Product;
/// string copyright = AssemblyInfo.Copyright;
/// string trademark = AssemblyInfo.Trademark;
/// string title = AssemblyInfo.Title;
/// string description = AssemblyInfo.Description;
/// string configuration = AssemblyInfo.Configuration;
/// string fileversion = AssemblyInfo.FileVersion;
/// Version version = AssemblyInfo.Version;
/// string versionFull = AssemblyInfo.VersionFull;
/// string versionMajor = AssemblyInfo.VersionMajor;
/// string versionMinor = AssemblyInfo.VersionMinor;
/// string versionBuild = AssemblyInfo.VersionBuild;
/// string versionRevision = AssemblyInfo.VersionRevision;
/// </example>
static public class AssemblyInfo
{
public static string Company { get { return GetExecutingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
public static string Product { get { return GetExecutingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
public static string Copyright { get { return GetExecutingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
public static string Trademark { get { return GetExecutingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
public static string Title { get { return GetExecutingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
public static string Description { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
public static string Configuration { get { return GetExecutingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
public static string FileVersion { get { return GetExecutingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }
public static Version Version { get { return Assembly.GetExecutingAssembly().GetName().Version; } }
public static string VersionFull { get { return Version.ToString(); } }
public static string VersionMajor { get { return Version.Major.ToString(); } }
public static string VersionMinor { get { return Version.Minor.ToString(); } }
public static string VersionBuild { get { return Version.Build.ToString(); } }
public static string VersionRevision { get { return Version.Revision.ToString(); } }
private static string GetExecutingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
{
T attribute = (T)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(T));
return value.Invoke(attribute);
}
}
/// <summary>
/// Gets the values from the AssemblyInfo.cs file for the previous assembly
/// </summary>
/// <example>
/// AssemblyInfoCalling assembly = new AssemblyInfoCalling();
/// string company1 = assembly.Company;
/// string product1 = assembly.Product;
/// string copyright1 = assembly.Copyright;
/// string trademark1 = assembly.Trademark;
/// string title1 = assembly.Title;
/// string description1 = assembly.Description;
/// string configuration1 = assembly.Configuration;
/// string fileversion1 = assembly.FileVersion;
/// Version version1 = assembly.Version;
/// string versionFull1 = assembly.VersionFull;
/// string versionMajor1 = assembly.VersionMajor;
/// string versionMinor1 = assembly.VersionMinor;
/// string versionBuild1 = assembly.VersionBuild;
/// string versionRevision1 = assembly.VersionRevision;
/// </example>
public class AssemblyInfoCalling
{
/// <summary>
/// Initializes a new instance of the <see cref="AssemblyInfoCalling"/> class.
/// </summary>
/// <param name="traceLevel">The trace level needed to get correct assembly
/// - will need to adjust based on where you put these classes in your project(s).</param>
public AssemblyInfoCalling(int traceLevel = 4)
{
//----------------------------------------------------------------------
// Default to "3" as the number of levels back in the stack trace to get the
// correct assembly for "calling" assembly
//----------------------------------------------------------------------
StackTraceLevel = traceLevel;
}
//----------------------------------------------------------------------
// Standard assembly attributes
//----------------------------------------------------------------------
public string Company { get { return GetCallingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
public string Product { get { return GetCallingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
public string Copyright { get { return GetCallingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
public string Trademark { get { return GetCallingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
public string Title { get { return GetCallingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
public string Description { get { return GetCallingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
public string Configuration { get { return GetCallingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
public string FileVersion { get { return GetCallingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }
//----------------------------------------------------------------------
// Version attributes
//----------------------------------------------------------------------
public static Version Version
{
get
{
//----------------------------------------------------------------------
// Get the assembly, return empty if null
//----------------------------------------------------------------------
Assembly assembly = GetAssembly(StackTraceLevel);
return assembly == null ? new Version() : assembly.GetName().Version;
}
}
public string VersionFull { get { return Version.ToString(); } }
public string VersionMajor { get { return Version.Major.ToString(); } }
public string VersionMinor { get { return Version.Minor.ToString(); } }
public string VersionBuild { get { return Version.Build.ToString(); } }
public string VersionRevision { get { return Version.Revision.ToString(); } }
//----------------------------------------------------------------------
// Set how deep in the stack trace we're looking - allows for customized changes
//----------------------------------------------------------------------
public static int StackTraceLevel { get; set; }
/// <summary>
/// Gets the calling assembly attribute.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <example>return GetCallingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company);</example>
/// <returns></returns>
private string GetCallingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
{
//----------------------------------------------------------------------
// Get the assembly, return empty if null
//----------------------------------------------------------------------
Assembly assembly = GetAssembly(StackTraceLevel);
if (assembly == null) return string.Empty;
//----------------------------------------------------------------------
// Get the attribute value
//----------------------------------------------------------------------
T attribute = (T) Attribute.GetCustomAttribute(assembly, typeof (T));
return value.Invoke(attribute);
}
/// <summary>
/// Go through the stack and gets the assembly
/// </summary>
/// <param name="stackTraceLevel">The stack trace level.</param>
/// <returns></returns>
private static Assembly GetAssembly(int stackTraceLevel)
{
//----------------------------------------------------------------------
// Get the stack frame, returning null if none
//----------------------------------------------------------------------
StackTrace stackTrace = new StackTrace();
StackFrame[] stackFrames = stackTrace.GetFrames();
if (stackFrames == null) return null;
//----------------------------------------------------------------------
// Get the declaring type from the associated stack frame, returning null if nonw
//----------------------------------------------------------------------
var declaringType = stackFrames[stackTraceLevel].GetMethod().DeclaringType;
if (declaringType == null) return null;
//----------------------------------------------------------------------
// Return the assembly
//----------------------------------------------------------------------
var assembly = declaringType.Assembly;
return assembly;
}
}

Related

How to add extension points in my library?

I've started writing DataFilters a while ago after I discovered and used elastic search with it's wonderful lucene syntax.
The idea behind that project was first to learn new stuff but I was also wondering if I could create something similar to work with other datasources.
Long story short, I now have something that work pretty well (I think) with the BCL classes and I now want to extend it to support third party libraries like NodaTime.
The main parts are IFilter interface
using System;
namespace DataFilters
{
/// <summary>
/// Defines the basic shape of a filter
/// </summary>
public interface IFilter : IEquatable<IFilter>
{
/// <summary>
/// Gets the JSON representation of the filter
/// </summary>
/// <returns></returns>
string ToJson();
/// <summary>
/// Computes a new <see cref="IFilter"/> instance which is the exact opposite of the current instance.
/// </summary>
/// <returns>The exact opposite of the current instance.</returns>
IFilter Negate();
#if NETSTANDARD2_1
public virtual void ToString() => ToJson();
#endif
}
}
with two implementations :
Filter
using DataFilters.Converters;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Schema;
using static Newtonsoft.Json.DefaultValueHandling;
using static Newtonsoft.Json.Required;
using System.Text.RegularExpressions;
#if !NETSTANDARD1_3
using System.Text.Json.Serialization;
#endif
namespace DataFilters
{
/// <summary>
/// An instance of this class holds a filter
/// </summary>
#if NETSTANDARD1_3
[JsonObject]
[JsonConverter(typeof(FilterConverter))]
#else
[System.Text.Json.Serialization.JsonConverter(typeof(FilterConverter))]
#endif
public class Filter : IFilter, IEquatable<Filter>
{
/// <summary>
/// Filter that always returns <c>true</c>
/// </summary>
public static Filter True => new Filter(default, default);
/// <summary>
/// Pattern that field name should respect.
/// </summary>
/// <returns></returns>
public const string ValidFieldNamePattern = #"[a-zA-Z_]+((\[""[a-zA-Z0-9_]+""]|(\.[a-zA-Z0-9_]+))*)";
/// <summary>
/// Regular expression used to validate
/// </summary>
/// <returns></returns>
public static readonly Regex ValidFieldNameRegex = new Regex(ValidFieldNamePattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1));
/// <summary>
/// Name of the json property that holds the field name
/// </summary>
public const string FieldJsonPropertyName = "field";
/// <summary>
/// Name of the json property that holds the operator
/// </summary>
public const string OperatorJsonPropertyName = "op";
/// <summary>
/// Name of the json property that holds the value
/// </summary>
public const string ValueJsonPropertyName = "value";
/// <summary>
/// <see cref="FilterOperator"/>s that required <see cref="Value"/> to be null.
/// </summary>
public static IEnumerable<FilterOperator> UnaryOperators { get; } = new[]{
FilterOperator.IsEmpty,
FilterOperator.IsNotEmpty,
FilterOperator.IsNotNull,
FilterOperator.IsNull
};
/// <summary>
/// Generates the <see cref="JSchema"/> for the specified <see cref="FilterOperator"/>.
/// </summary>
/// <param name="op"></param>
/// <returns></returns>
public static JSchema Schema(FilterOperator op)
{
JSchema schema;
switch (op)
{
case FilterOperator.Contains:
case FilterOperator.StartsWith:
case FilterOperator.EndsWith:
schema = new JSchema
{
Type = JSchemaType.Object,
Properties =
{
[FieldJsonPropertyName] = new JSchema { Type = JSchemaType.String },
[OperatorJsonPropertyName] = new JSchema { Type = JSchemaType.String },
[ValueJsonPropertyName] = new JSchema { Type = JSchemaType.String }
},
Required = { FieldJsonPropertyName, OperatorJsonPropertyName }
};
break;
case FilterOperator.IsEmpty:
case FilterOperator.IsNotEmpty:
case FilterOperator.IsNotNull:
case FilterOperator.IsNull:
schema = new JSchema
{
Type = JSchemaType.Object,
Properties =
{
[FieldJsonPropertyName] = new JSchema { Type = JSchemaType.String },
[OperatorJsonPropertyName] = new JSchema { Type = JSchemaType.String }
},
Required = { FieldJsonPropertyName, OperatorJsonPropertyName }
};
break;
default:
schema = new JSchema
{
Type = JSchemaType.Object,
Properties =
{
[FieldJsonPropertyName] = new JSchema { Type = JSchemaType.String, },
[OperatorJsonPropertyName] = new JSchema { Type = JSchemaType.String },
[ValueJsonPropertyName] = new JSchema {
Not = new JSchema() { Type = JSchemaType.Null }
}
},
Required = { FieldJsonPropertyName, OperatorJsonPropertyName, ValueJsonPropertyName }
};
break;
}
schema.AllowAdditionalProperties = false;
return schema;
}
/// <summary>
/// Name of the field the filter will be applied to
/// </summary>
#if NETSTANDARD1_3
[JsonProperty(FieldJsonPropertyName, Required = Always)]
#else
[JsonPropertyName(FieldJsonPropertyName)]
#endif
public string Field { get; }
/// <summary>
/// Operator to apply to the filter
/// </summary>
#if NETSTANDARD1_3
[JsonProperty(OperatorJsonPropertyName, Required = Always)]
[JsonConverter(typeof(CamelCaseEnumTypeConverter))]
#else
[JsonPropertyName(OperatorJsonPropertyName)]
//[System.Text.Json.Serialization.JsonConverter(typeof(FilterOperatorConverter))]
#endif
public FilterOperator Operator { get; }
/// <summary>
/// Value of the filter
/// </summary>
#if NETSTANDARD1_3
[JsonProperty(ValueJsonPropertyName,
Required = AllowNull,
DefaultValueHandling = IgnoreAndPopulate,
NullValueHandling = NullValueHandling.Ignore)]
#else
[JsonPropertyName(ValueJsonPropertyName)]
#endif
public object Value { get; }
/// <summary>
/// Builds a new <see cref="Filter"/> instance.
/// </summary>
/// <param name="field">name of the field</param>
/// <param name="operator"><see cref="Filter"/> to apply</param>
/// <param name="value">value of the filter</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="field"/> does not conform with <see cref="ValidFieldNamePattern"/></exception>
public Filter(string field, FilterOperator #operator, object value = null)
{
if (!string.IsNullOrEmpty(field) && !ValidFieldNameRegex.IsMatch(field))
{
throw new ArgumentOutOfRangeException(nameof(field), field, $"field name is not valid ({ValidFieldNamePattern}).");
}
Field = field;
switch (#operator)
{
case FilterOperator.EqualTo when value is null:
Operator = FilterOperator.IsNull;
break;
case FilterOperator.NotEqualTo when value is null:
Operator = FilterOperator.IsNotNull;
break;
default:
Operator = #operator;
Value = value;
break;
}
}
#if NETSTANDARD1_3
public string ToJson()
{
return this.Jsonify(new JsonSerializerSettings());
}
#else
public string ToJson() => this.Jsonify();
#endif
public override string ToString() => ToJson();
public bool Equals(Filter other)
=> other != null
&& (ReferenceEquals(other, this)
|| (Equals(other.Field, Field) && Equals(other.Operator, Operator) && Equals(other.Value, Value)));
public override bool Equals(object obj) => Equals(obj as Filter);
#if NETSTANDARD1_3 || NETSTANDARD2_0
public override int GetHashCode() => (Field, Operator, Value).GetHashCode();
#else
public override int GetHashCode() => HashCode.Combine(Field, Operator, Value);
#endif
public IFilter Negate()
{
FilterOperator #operator = Operator switch
{
FilterOperator.EqualTo => FilterOperator.NotEqualTo,
FilterOperator.NotEqualTo => FilterOperator.EqualTo,
FilterOperator.IsNull => FilterOperator.IsNotNull,
FilterOperator.IsNotNull => FilterOperator.IsNull,
FilterOperator.LessThan => FilterOperator.GreaterThan,
FilterOperator.GreaterThan => FilterOperator.LessThan,
FilterOperator.GreaterThanOrEqual => FilterOperator.LessThanOrEqualTo,
FilterOperator.StartsWith => FilterOperator.NotStartsWith,
FilterOperator.NotStartsWith => FilterOperator.StartsWith,
FilterOperator.EndsWith => FilterOperator.NotEndsWith,
FilterOperator.NotEndsWith => FilterOperator.EndsWith,
FilterOperator.Contains => FilterOperator.NotContains,
FilterOperator.IsEmpty => FilterOperator.IsNotEmpty,
FilterOperator.IsNotEmpty => FilterOperator.IsEmpty,
FilterOperator.LessThanOrEqualTo => FilterOperator.GreaterThanOrEqual,
_ => throw new ArgumentOutOfRangeException(nameof(Operator), "Unknown operator"),
};
return new Filter(Field, #operator, Value);
}
public bool Equals(IFilter other) => Equals(other as Filter)
;
public void Deconstruct(out string field, out FilterOperator #operator, out object value)
{
field = Field;
#operator = Operator;
value = Value;
}
}
}
MultiFilter
using DataFilters.Converters;
using Newtonsoft.Json;
using Newtonsoft.Json.Schema;
using System;
using System.Collections.Generic;
using System.Linq;
using static Newtonsoft.Json.DefaultValueHandling;
using static Newtonsoft.Json.Required;
#if !NETSTANDARD1_3
using System.Text.Json.Serialization;
#endif
namespace DataFilters
{
/// <summary>
/// An instance of this class holds combination of <see cref="IFilter"/>
/// </summary>
[JsonObject]
#if NETSTANDARD1_3
[JsonConverter(typeof(MultiFilterConverter))]
#else
[System.Text.Json.Serialization.JsonConverter(typeof(MultiFilterConverter))]
#endif
public class MultiFilter : IFilter, IEquatable<MultiFilter>
{
/// <summary>
/// Name of the json property that holds filter's filters collection.
/// </summary>
public const string FiltersJsonPropertyName = "filters";
/// <summary>
/// Name of the json property that holds the composite filter's logic
/// </summary>
public const string LogicJsonPropertyName = "logic";
public static JSchema Schema => new JSchema
{
Type = JSchemaType.Object,
Properties =
{
[FiltersJsonPropertyName] = new JSchema { Type = JSchemaType.Array, MinimumItems = 2 },
[LogicJsonPropertyName] = new JSchema { Type = JSchemaType.String, Default = "and"}
},
Required = { FiltersJsonPropertyName },
AllowAdditionalProperties = false
};
/// <summary>
/// Collections of filters
/// </summary>
#if NETSTANDARD1_3
[JsonProperty(PropertyName = FiltersJsonPropertyName, Required = Always)]
#else
[JsonPropertyName(FiltersJsonPropertyName)]
#endif
public IEnumerable<IFilter> Filters { get; set; } = Enumerable.Empty<IFilter>();
/// <summary>
/// Operator to apply between <see cref="Filters"/>
/// </summary>
#if NETSTANDARD1_3
[JsonProperty(PropertyName = LogicJsonPropertyName, DefaultValueHandling = IgnoreAndPopulate)]
[JsonConverter(typeof(CamelCaseEnumTypeConverter))]
#else
[JsonPropertyName(LogicJsonPropertyName)]
#endif
public FilterLogic Logic { get; set; }
public virtual string ToJson() => this.Jsonify();
public IFilter Negate()
{
MultiFilter filter = new MultiFilter
{
Logic = Logic switch
{
FilterLogic.And => FilterLogic.Or,
FilterLogic.Or => FilterLogic.And,
_ => throw new ArgumentOutOfRangeException($"Unsupported {Logic}")
},
Filters = Filters.Select(f => f.Negate())
#if DEBUG
.ToArray()
#endif
};
return filter;
}
#if NETSTANDARD1_3 || NETSTANDARD2_0
public override int GetHashCode() => (Logic, Filters).GetHashCode();
#else
public override int GetHashCode()
{
HashCode hash = new HashCode();
hash.Add(Logic);
foreach (IFilter filter in Filters)
{
hash.Add(filter);
}
return hash.ToHashCode();
}
#endif
public bool Equals(IFilter other) => Equals(other as MultiFilter);
public override bool Equals(object obj) => Equals(obj as MultiFilter);
public bool Equals(MultiFilter other)
=> Logic == other?.Logic
&& Filters.Count() == other?.Filters?.Count()
&& Filters.All(filter => other?.Filters?.Contains(filter) ?? false)
&& (other?.Filters.All(filter => Filters.Contains(filter)) ?? false);
}
}
DataFilters.Expressions and DataFilters.Queries are two libraries that I also wrote and that allow to create C# Expressions or WHERE SQLs given an IFilter instance as a input (extension methods).
What i'm trying to do now is to provide an extension point so that I could write a new library (called DataFilters.NodaTime for example) that could handle NodaTime types somehow while deferring everything else to DataFilters.Expressions (a library that I already released).
That extension point should add ability to handle nodatime type but I have no clue how to get started on this
For now, I'm thinking about something like this :
create a new library DataFilters.Expressions.NodaTime
create a new IFilter extension method in it : it will be tailored to handle NodaTime types.
The goal is to be able to handle NodaTime types both with DataFilters.Expressions and DataFilters.Queries for example.
Could it be a good approach or is there a better way to handle this ?
Thanks in advance to anyone who could help me on this

How to apply custom information on a function to show up when called in Visual Studio

I have a class that adds some functionality to my strings.
public static class StringExtensions
{
public static string formString(this string value)
{
value = value.Replace("\t", " ");
value = value.Trim();
return value;
}
}
How can I add some explanation for the called function
similarly to what appears when .ToString() is called:
You'll have to add an XML comment above the method.
/// <summary>
/// Some informative description
/// </summary>
/// <returns>A description of the return value</returns>
public static string formString(this string value)
{
value = value.Replace("\t", " ");
value = value.Trim();
return value;
}

System.Reflection.TargetInvocationException in constructor

I am keep getting
System.Reflection.TargetInvocationException
and PresentationFramework.dll, additional info Exception has been thrown by the target of an invocation.
Can someone please help me out here?
Info:
Call Stack
PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader xamlReader, System.Xaml.IXamlObjectWriterFactory writerFactory, bool skipJournaledProperties, object rootObject, System.Xaml.XamlObjectWriterSettings settings, System.Uri baseUri) Unknown
namespace PMD.Analysis.AnalysisViewModel
{
using PMD.Measurement.MeasurementModel;
using System.Windows.Data;
using PMD.Analysis.AnalysisModel;
using System;
using System.Collections.Generic;
using PMD.Measurement.MeasurementViewModel;
public class AnalysisViewModel : ViewModel
{
/// <summary>
/// New analysis command.
/// </summary>
private ICommand newAnalysis = null;
public PMD.Analysis.AnalysisViewModel.NewAnalysisViewModel m_NewAnalysisViewModel;
Measurement measurement = new Measurement();
private ICollectionView measurements = null;
/// <summary>
/// Measurement's search by title field.
/// </summary>
private string searchTitle;
/// <summary>
/// Measurement's search by title field.
/// </summary>
private string searchTester;
/// <summary>
/// Measurement's search by vehicle VIN field.
/// </summary>
private string searchVehicleVIN;
public MeasurementModel MeasurementModel
{
get;
set;
}
public enum SelectedState
{
// No Masurements.
Inactive,
// Masurements.
Active,
// Waiting for Masurements.
WaitingAnswer
};
public SelectedState CurrentSelectedState { get; set; }
public Analysis Analysis
{
get;
set;
}
public AnalysisViewModel()
{
Analysis = new Analysis();
measurements = new ListCollectionView(MeasurementModel.Measurements);
measurements.Filter = new Predicate<object>(SearchCallbackAnalysis);
}
~AnalysisViewModel()
{
}
/// <summary>
/// List of measurements that will be displayed in analysis view.
/// </summary>
public ICollectionView Measurements
{
get { return measurements; }
set { measurements = value; }
}
/// <summary>
/// Gets or sets new analysis command.
/// </summary>
public ICommand NewAnalysis
{
get
{
if (newAnalysis == null)
newAnalysis = new NewAnalysisCommand(this);
return newAnalysis;
}
}
public bool SearchCallbackAnalysis(object item)
{
bool isItemShowed = true;
if ((searchTitle != "") && (searchTitle != null))
isItemShowed &= (((Measurement)item).Title == searchTitle);
if ((searchVehicleVIN != "") && (searchVehicleVIN != null))
isItemShowed &= (((Measurement)item).Vehicle.VehicleVIN == searchVehicleVIN);
if ((SearchTester != "") && (SearchTester != null))
isItemShowed &= (((Measurement)item).Tester == SearchTester);
return isItemShowed;
}
/// <summary>
/// Gets or sets measurement's search by title field.
/// </summary>
public string SearchTitle
{
get
{
return searchTitle;
}
set
{
searchTitle = value;
Measurements.Refresh();
}
}
/// <summary>
/// Gets or sets measurement's search by tester name field.
/// </summary>
public string SearchTester
{
get
{
return searchTester;
}
set
{
searchTester = value;
Measurements.Refresh();
}
}
/// <summary>
/// Gets or sets measurement's search by vehicle VIN field.
/// </summary>
public string SearchVehicleVIN
{
get
{
return searchVehicleVIN;
}
set
{
searchVehicleVIN = value;
Measurements.Refresh();
}
}
}//end AnalysisViewModel
}//end namespace AnalysisViewModel
if i comment in constructor this line of code:
measurements.Filter = new Predicate<object>(SearchCallbackAnalysis);
Everything works fine but i need this line to search in the list.
Additional info:
xamlReader Cannot obtain value of local or argument 'xamlReader' as it is not available at this instruction pointer, possibly because it has been optimized away. System.Xaml.XamlReader
writerFactory Cannot obtain value of local or argument 'writerFactory' as it is not available at this instruction pointer, possibly because it has been optimized away. System.Xaml.IXamlObjectWriterFactory
skipJournaledProperties Cannot obtain value of local or argument 'skipJournaledProperties' as it is not available at this instruction pointer, possibly because it has been optimized away. bool
rootObject Cannot obtain value of local or argument 'rootObject' as it is not available at this instruction pointer, possibly because it has been optimized away. object
settings Cannot obtain value of local or argument 'settings' as it is not available at this instruction pointer, possibly because it has been optimized away. System.Xaml.XamlObjectWriterSettings
baseUri Cannot obtain value of local or argument 'baseUri' as it is not available at this instruction pointer, possibly because it has been optimized away. System.Uri
i have try:
public ICollectionView Measurements
{
get { return measurements; }
set { measurements = value;
measurements.Filter = new Predicate<object>(SearchCallbackAnalysis);
}
}
Now everything works fine. Thank you for try to help me.

Postsharp MethodInterceptionAspect attribute throws EntrypointNotFoundException

I have recently updated PostSharp to v4.1.13 and I have started receiving this error when I try to build my solution:
The custom attribute 'True.Kentico.Caching.KenticoCacheAttribute' constructor threw the exception EntryPointNotFoundException: Entry point was not found.
This attribute implements caching, and has worked before, so I'm wondering what would be the cause of it breaking. I am using this attribute in other assemblies referencing the aspect's containing assembly, and I get that error in there as well.
The following is the code for the attribute. Apologies, it contains a number of constructors.
[Serializable]
public class KenticoCacheAttribute : MethodInterceptionAspect
{
public int CacheMinutes { get; set; }
/// <summary>
/// the string value of the cache dependency key. If it uses parameters from the method, include a {0} to format with the method parameter
/// </summary>
public string CacheDependency { get; set; }
public string[] CacheDependencyStrings { get; set; }
public KenticoCacheDependencyObtainFrom ObtainCacheDependencyFrom { get; set; }
/// <summary>
/// whether caching is enabled - default from app settings
/// </summary>
public bool CacheEnabled { get; set; }
/// <summary>
/// this is the index of the parameter that will be used to format the cachedependency, if required
/// </summary>
public int CacheDependencyParameterIndex { get; set; }
public string CacheDependencyObjectProperty { get; set; }
private string _methodName;
/// <summary>
/// initializes the cache attribute to use a static dependency
/// </summary>
/// <param name="cacheDependency"></param>
public KenticoCacheAttribute(string cacheDependency)
{
CacheMinutes = EngineContext.Current.Resolve<AppSettings>().Cache.TTL.GlobalSetting;
CacheEnabled = !EngineContext.Current.Resolve<AppSettings>().Cache.IgnoreCache;
CacheDependencyParameterIndex = -1;
CacheDependency = cacheDependency;
if (String.IsNullOrEmpty(cacheDependency))
ObtainCacheDependencyFrom = KenticoCacheDependencyObtainFrom.NoDependency;
else
{
ObtainCacheDependencyFrom = KenticoCacheDependencyObtainFrom.Static;
}
}
/// <summary>
/// initializes the cache attribute to use a static dependency using multiple depndencies
/// </summary>
/// <param name="cacheDependencystrings">an array of strings</param>
public KenticoCacheAttribute(string[] cacheDependencystrings)
{
CacheMinutes = EngineContext.Current.Resolve<AppSettings>().Cache.TTL.GlobalSetting;
CacheEnabled = !EngineContext.Current.Resolve<AppSettings>().Cache.IgnoreCache;
CacheDependencyParameterIndex = -1;
CacheDependencyStrings = cacheDependencystrings;
ObtainCacheDependencyFrom = KenticoCacheDependencyObtainFrom.MultipleDependenciesStatic;
}
/// <summary>
/// initializes the cache attribute to take the dependency from the input parameter
/// </summary>
/// <param name="cacheDependency">the static string to be used for the cache dependency. you may include {CurrentSiteName} to be replaced with the current site name, and {0} to be replaced with the value passed in as one of the method parameters</param>
/// <param name="cacheDependencyParameterIndex">the index of the parameter in the method parameters that will be used to create the cache dependency key</param>
public KenticoCacheAttribute(string cacheDependency, int cacheDependencyParameterIndex)
{
CacheMinutes = EngineContext.Current.Resolve<AppSettings>().Cache.TTL.GlobalSetting;
CacheEnabled = !EngineContext.Current.Resolve<AppSettings>().Cache.IgnoreCache;
CacheDependencyParameterIndex = cacheDependencyParameterIndex;
CacheDependency = cacheDependency;
if (String.IsNullOrEmpty(cacheDependency))
{
ObtainCacheDependencyFrom = KenticoCacheDependencyObtainFrom.MultipleDependenciesFromParameter;
}
else
{
ObtainCacheDependencyFrom = KenticoCacheDependencyObtainFrom.FromMethodParameter;
}
}
/// <summary>
/// initialize the cache attribute to obtain the cache dependency from the named property of the return object
/// </summary>
/// <param name="cacheDependency">the static string to be used for the cache dependency. you may include {CurrentSiteName} to be replaced with the current site name, and {0} to be replaced with the value in the named parameter </param>
/// <param name="cacheDependencyObjectPropertyName">the name of the property of the return object that will be used to replace the placeholder in the static string to build the cache dependency string</param>
public KenticoCacheAttribute(string cacheDependency, string cacheDependencyObjectPropertyName)
{
CacheMinutes = EngineContext.Current.Resolve<AppSettings>().Cache.TTL.GlobalSetting;
CacheEnabled = !EngineContext.Current.Resolve<AppSettings>().Cache.IgnoreCache;
CacheDependencyParameterIndex = -1;
CacheDependency = cacheDependency;
ObtainCacheDependencyFrom = KenticoCacheDependencyObtainFrom.FromReturnObject;
CacheDependencyObjectProperty = cacheDependencyObjectPropertyName;
}
/// <summary>
/// initialize the cache attribute to obtain the cache dependency from the named property of the return object
/// </summary>
/// <param name="cacheDependency">the static string to be used for the cache dependency. you may include {CurrentSiteName} to be replaced with the current site name, and {0} to be replaced with the value in the named parameter </param>
/// <param name="cacheDependencyParameterIndex"></param>
/// <param name="cacheDependencyObjectPropertyName">the name of the property of the return object that will be used to replace the placeholder in the static string to build the cache dependency string</param>
public KenticoCacheAttribute(string cacheDependency, int cacheDependencyParameterIndex, string cacheDependencyObjectPropertyName)
{
CacheMinutes = EngineContext.Current.Resolve<AppSettings>().Cache.TTL.GlobalSetting;
CacheEnabled = !EngineContext.Current.Resolve<AppSettings>().Cache.IgnoreCache;
CacheDependencyParameterIndex = cacheDependencyParameterIndex;
CacheDependency = cacheDependency;
ObtainCacheDependencyFrom = KenticoCacheDependencyObtainFrom.FromMethodParameterObjectProperty;
CacheDependencyObjectProperty = cacheDependencyObjectPropertyName;
}
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
_methodName = method.Name;
}
public override void OnInvoke(MethodInterceptionArgs args)
{
var methodInfo = args.Method as MethodInfo;
if (methodInfo != null && (methodInfo.ReturnType != typeof(void) && CacheEnabled))
{
var cacheKey = BuildCacheKey(args.Arguments);
var cacheSettings = new CacheSettings(CacheMinutes, cacheKey);
var data = CacheHelper.Cache(cs => GetData(cs, args), cacheSettings);
args.ReturnValue = data;
}
else
base.OnInvoke(args);
}
private object GetData(CacheSettings cs, MethodInterceptionArgs args)
{
var data = args.Invoke(args.Arguments);
// Checks whether data was loaded and whether the data should be cached (based on the CacheSettings)
if ((data != null) && cs.Cached)
{
// Sets a cache dependency for the data
// The data is removed from the cache if the objects represented by the dummy key are modified (all user objects in this case)
var dependencyResolver = CacheDependencyFactory.GetDependecyFormatter(ObtainCacheDependencyFrom);
var dependencyString = dependencyResolver.Format(new CacheDependencyFormatParameters()
{
CacheDependencyBase = CacheDependency,
CacheDependencybaseString = CacheDependencyStrings,
InputParameterIndex = CacheDependencyParameterIndex,
ReturnParameterName = CacheDependencyObjectProperty,
InputParameterData = args,
ReturnParameterData = data
});
cs.CacheDependency = CacheHelper.GetCacheDependency(dependencyString);
}
return data;
}
private string BuildCacheKey(Arguments arguments)
{
var sb = new StringBuilder();
sb.Append(_methodName);
foreach (var argument in arguments.ToArray())
{
sb.Append(argument == null ? "_" : argument.ToString());
}
sb.Append(String.Format("{0}_{1}", SiteContext.CurrentSiteName,
SiteContext.CurrentSite.DefaultVisitorCulture));
return sb.ToString();
}
}
Any help would be appreciated!
So it turns out that the issue is with these lines of code in the constructors:
CacheMinutes = EngineContext.Current.Resolve<AppSettings>().Cache.TTL.GlobalSetting;
CacheEnabled = !EngineContext.Current.Resolve<AppSettings>().Cache.IgnoreCache;
When PostSharp runs, The dependencyInjection framework has not yet been initialised, so the execution fails. It's strange that it was working before, but hey. I moved this code into the OnInvoke method, which should only run when the DI Enginecontext has been initialised :
public override void OnInvoke(MethodInterceptionArgs args)
{
CacheMinutes = EngineContext.Current.Resolve<AppSettings>().Cache.TTL.GlobalSetting;
CacheEnabled = !EngineContext.Current.Resolve<AppSettings>().Cache.IgnoreCache;
var methodInfo = args.Method as MethodInfo;
......

C# - Get calling method's Assembly?

Is there a way in C# to get the Assembly of the calling method? (Not the current method.)
i.e. I want the executing assembly, one above in the call stack.
Try this
Assembly.GetCallingAssembly();
How about this:
StackTrace stackTrace = new StackTrace(); // get call stack
var assembly = stackTrace.GetFrame(0).GetMethod().DeclaringType.Assembly;
With help from http://www.csharp-examples.net/reflection-callstack/
This is what I use:
var stackFrames = new StackTrace().GetFrames();
if(stackFrames==null) return null;
var executingAssembly = Assembly.GetExecutingAssembly();
foreach (var frame in stackFrames)
{
var assembly = frame.GetMethod().DeclaringType.Assembly;
if (assembly != executingAssembly)
{
return assembly;
}
}
return null;
No it's not possible to reliably understand who is calling you. Some people will undoubtedly suggest a stack walk but that is unreliable due to JIT inlining. There is just no way to reliably get the method / assembly which is calling your method.
Wrote this to get the AssemblyInfo.cs attributes for the calling assembly -- so uses the "GetAssembly(int stackTraceLevel)" method that does what is needed...
All this is also up on my blog at http://lancelarsen.com/reading-values-from-assemblyinfo-cs/
Enjoy
/// <summary>
/// Gets the values from the AssemblyInfo.cs file for the previous assembly
/// </summary>
/// <example>
/// AssemblyInfoCalling assembly = new AssemblyInfoCalling();
/// string company1 = assembly.Company;
/// string product1 = assembly.Product;
/// string copyright1 = assembly.Copyright;
/// string trademark1 = assembly.Trademark;
/// string title1 = assembly.Title;
/// string description1 = assembly.Description;
/// string configuration1 = assembly.Configuration;
/// string fileversion1 = assembly.FileVersion;
/// Version version1 = assembly.Version;
/// string versionFull1 = assembly.VersionFull;
/// string versionMajor1 = assembly.VersionMajor;
/// string versionMinor1 = assembly.VersionMinor;
/// string versionBuild1 = assembly.VersionBuild;
/// string versionRevision1 = assembly.VersionRevision;
/// </example>
public class AssemblyInfoCalling
{
/// <summary>
/// Initializes a new instance of the <see cref="AssemblyInfoCalling"/> class.
/// </summary>
/// <param name="traceLevel">The trace level needed to get correct assembly
/// - will need to adjust based on where you put these classes in your project(s).</param>
public AssemblyInfoCalling(int traceLevel = 4)
{
//----------------------------------------------------------------------
// Default to "3" as the number of levels back in the stack trace to get the
// correct assembly for "calling" assembly
//----------------------------------------------------------------------
StackTraceLevel = traceLevel;
}
//----------------------------------------------------------------------
// Standard assembly attributes
//----------------------------------------------------------------------
public string Company { get { return GetCallingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company); } }
public string Product { get { return GetCallingAssemblyAttribute<AssemblyProductAttribute>(a => a.Product); } }
public string Copyright { get { return GetCallingAssemblyAttribute<AssemblyCopyrightAttribute>(a => a.Copyright); } }
public string Trademark { get { return GetCallingAssemblyAttribute<AssemblyTrademarkAttribute>(a => a.Trademark); } }
public string Title { get { return GetCallingAssemblyAttribute<AssemblyTitleAttribute>(a => a.Title); } }
public string Description { get { return GetCallingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
public string Configuration { get { return GetCallingAssemblyAttribute<AssemblyDescriptionAttribute>(a => a.Description); } }
public string FileVersion { get { return GetCallingAssemblyAttribute<AssemblyFileVersionAttribute>(a => a.Version); } }
//----------------------------------------------------------------------
// Version attributes
//----------------------------------------------------------------------
public static Version Version
{
get
{
//----------------------------------------------------------------------
// Get the assembly, return empty if null
//----------------------------------------------------------------------
Assembly assembly = GetAssembly(StackTraceLevel);
return assembly == null ? new Version() : assembly.GetName().Version;
}
}
public string VersionFull { get { return Version.ToString(); } }
public string VersionMajor { get { return Version.Major.ToString(); } }
public string VersionMinor { get { return Version.Minor.ToString(); } }
public string VersionBuild { get { return Version.Build.ToString(); } }
public string VersionRevision { get { return Version.Revision.ToString(); } }
//----------------------------------------------------------------------
// Set how deep in the stack trace we're looking - allows for customized changes
//----------------------------------------------------------------------
public static int StackTraceLevel { get; set; }
//----------------------------------------------------------------------
// Custom Attributes
//----------------------------------------------------------------------
public string Location
{
get
{
try
{
return GetCallingAssemblyAttribute<AssemblyLocationAttribute>(a => a.Value);
}
catch (NullReferenceException)
{
return string.Empty;
}
}
}
/// <summary>
/// Gets the calling assembly attribute.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <example>return GetCallingAssemblyAttribute<AssemblyCompanyAttribute>(a => a.Company);</example>
/// <returns></returns>
private string GetCallingAssemblyAttribute<T>(Func<T, string> value) where T : Attribute
{
//----------------------------------------------------------------------
// Get the assembly, return empty if null
//----------------------------------------------------------------------
Assembly assembly = GetAssembly(StackTraceLevel);
if (assembly == null) return string.Empty;
//----------------------------------------------------------------------
// Get the attribute value
//----------------------------------------------------------------------
T attribute = (T) Attribute.GetCustomAttribute(assembly, typeof (T));
return value.Invoke(attribute);
}
/// <summary>
/// Go through the stack and gets the assembly
/// </summary>
/// <param name="stackTraceLevel">The stack trace level.</param>
/// <returns></returns>
private static Assembly GetAssembly(int stackTraceLevel)
{
//----------------------------------------------------------------------
// Get the stack frame, returning null if none
//----------------------------------------------------------------------
StackTrace stackTrace = new StackTrace();
StackFrame[] stackFrames = stackTrace.GetFrames();
if (stackFrames == null) return null;
//----------------------------------------------------------------------
// Get the declaring type from the associated stack frame, returning null if nonw
//----------------------------------------------------------------------
var declaringType = stackFrames[stackTraceLevel].GetMethod().DeclaringType;
if (declaringType == null) return null;
//----------------------------------------------------------------------
// Return the assembly
//----------------------------------------------------------------------
var assembly = declaringType.Assembly;
return assembly;
}
}
Came across this looking for something similar. In my case, it was Assembly.GetEntryAssembly().
Use Case
Program A runs CodeDomProvider.CompileAssemblyFromSource to embed resources and compile Program B. DLL in Program B then reads resources, but doesn't know the Assembly (which the above solves).

Categories