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;
......
Related
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
My ASP.NET application runs fine in local instance of VS 2012 but not in VS 2015. It is throwing
Systems.Collections.Generic.KeyNotFoundException occurred in mscorlib.dll but not handled in user code
The application also runs fine when deployed on the server but issue occurs only in local machine - NHibernate session key being null and breaks on the following line.
var sessionInitializer = map[sessionFactory]
My code is pasted below and I am following similar implementation as in the following link (I have everything up until the IWindsorInstaller section from the link) -
http://nhibernate.info/blog/2011/03/02/effective-nhibernate-session-management-for-web-apps.html
public class LazyNHWebSessionContext : ICurrentSessionContext
{
private readonly ISessionFactoryImplementor factory;
private const string CurrentSessionContextKey =
"NHibernateCurrentSession";
public LazyNHWebSessionContext(ISessionFactoryImplementor factory)
{
this.factory = factory;
}
/// <summary>
/// Retrieve the current session for the session factory.
/// </summary>
/// <returns></returns>
public ISession CurrentSession()
{
Lazy<ISession> initializer;
var currentSessionFactoryMap = GetCurrentFactoryMap();
if (currentSessionFactoryMap == null ||
!currentSessionFactoryMap.TryGetValue(factory, out initializer))
{
return null;
}
return initializer.Value;
}
/// <summary>
/// Bind a new sessionInitializer to the context of the sessionFactory.
/// </summary>
/// <param name="sessionInitializer"></param>
/// <param name="sessionFactory"></param>
public static void Bind(Lazy<ISession> sessionInitializer, ISessionFactory sessionFactory)
{
var map = GetCurrentFactoryMap();
map[sessionFactory] = sessionInitializer;
}
/// <summary>
/// Unbind the current session of the session factory.
/// </summary>
/// <param name="sessionFactory"></param>
/// <returns></returns>
public static ISession UnBind(ISessionFactory sessionFactory)
{
var map = GetCurrentFactoryMap();
var sessionInitializer = map[sessionFactory];
map[sessionFactory] = null;
if (sessionInitializer == null || !sessionInitializer.IsValueCreated) return null;
return sessionInitializer.Value;
}
/// <summary>
/// Provides the CurrentMap of SessionFactories.
/// If there is no map create/store and return a new one.
/// </summary>
/// <returns></returns>
private static IDictionary<ISessionFactory, Lazy<ISession>> GetCurrentFactoryMap()
{
//var contextItem = HttpContext.Current.Items[CurrentSessionContextKey];
if (HttpContext.Current == null) return null;
var currentFactoryMap = (IDictionary<ISessionFactory, Lazy<ISession>>)
HttpContext.Current.Items[CurrentSessionContextKey];
if (currentFactoryMap == null)
{
currentFactoryMap = new Dictionary<ISessionFactory, Lazy<ISession>>();
HttpContext.Current.Items[CurrentSessionContextKey] = currentFactoryMap;
}
return currentFactoryMap;
}
}
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.
I'm using Entity Framework in my application with ChangeTracking Entities so I can have an Audit Log in my database for every Add, Modification, Delete (ColumnName, OriginalValue, NewValue, etc).
There are some functions that I'm not going to use Entity Framework because is very slow, for example bulk insert / update and other scenarios, instead I will user ADO.NET with Stored Procedures.
In order to keep tracking changes on both Entity Framework and ADO.NET I was thinking on use a Base Class for custom classes that will be populated from DataReaders and will need to track changes on those classes so I came up with:
public class NotifyPropertyChangeObject : INotifyPropertyChanged
{
/// <summary>
/// Track changes or not.
/// If we're working with DTOs and we fill up the DTO in the DAL we should not be tracking changes.
/// </summary>
private bool trackChanges = false;
/// <summary>
/// Changes to the object
/// </summary>
public List<TrackChange> Changes { get; private set; }
/// <summary>
/// Is the object dirty or not?
/// </summary>
public bool IsDirty
{
get { return Changes.Count > 0; }
set { ; }
}
/// <summary>
/// Event required for INotifyPropertyChanged
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// This constructor will initialize the change tracking
/// </summary>
public NotifyPropertyChangeObject()
{
// Change tracking default
trackChanges = true;
// New change tracking dictionary
Changes = new List<TrackChange>();
}
/// <summary>
/// Reset the object to non-dirty
/// </summary>
public void Reset()
{
Changes.Clear();
}
/// <summary>
/// Start tracking changes
/// </summary>
public void StartTracking()
{
trackChanges = true;
}
/// <summary>
/// Stop tracking changes
/// </summary>
public void StopTracking()
{
trackChanges = false;
}
/// <summary>
/// Change the property if required and throw event
/// </summary>
/// <param name="variable"></param>
/// <param name="property"></param>
/// <param name="value"></param>
public void ApplyPropertyChange<T, F>(ref F field, Expression<Func<T, object>> property, F value)
{
// Only do this if the value changes
if (field == null || !field.Equals(value))
{
// Get the property
var propertyExpression = GetMemberExpression(property);
if (propertyExpression == null)
throw new InvalidOperationException("You must specify a property");
// Property name
string propertyName = propertyExpression.Member.Name;
// If change tracking is enabled, we can track the changes...
if (trackChanges)
{
// Change tracking
var track = Changes.Where(c => c.Name == propertyName).FirstOrDefault();
if (track == null)
{
track = new TrackChange();
track.Name = propertyName;
track.Original = field;
track.Value = value;
Changes.Add(track);
}
else
{
track.Name = propertyName;
track.Original = field;
track.Value = value;
}
//Changes[propertyName] = value;
// Notify change
NotifyPropertyChanged(propertyName);
}
// Set the value
field = value;
}
}
/// <summary>
/// Get member expression
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="expression"></param>
/// <returns></returns>
public MemberExpression GetMemberExpression<T>(Expression<Func<T, object>> expression)
{
// Default expression
MemberExpression memberExpression = null;
// Convert
if (expression.Body.NodeType == ExpressionType.Convert)
{
var body = (UnaryExpression)expression.Body;
memberExpression = body.Operand as MemberExpression;
}
// Member access
else if (expression.Body.NodeType == ExpressionType.MemberAccess)
{
memberExpression = expression.Body as MemberExpression;
}
// Not a member access
if (memberExpression == null)
throw new ArgumentException("Not a member access", "expression");
// Return the member expression
return memberExpression;
}
/// <summary>
/// The property has changed
/// </summary>
/// <param name="propertyName"></param>
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// Convert the changes to an XML string
/// </summary>
/// <returns></returns>
public string ChangesToXml()
{
// Prepare base objects
XDeclaration declaration = new XDeclaration("1.0", Encoding.UTF8.HeaderName, String.Empty);
XElement root = new XElement("Changes");
// Create document
XDocument document = new XDocument(declaration, root);
// Add changes to the document
// TODO: If it's an object, maybe do some other things
//foreach (KeyValuePair<string, object> change in Changes)
// root.Add(new XElement(change.Key, change.Value));
// Get the XML
return document.Document.ToString();
}
}
public class TrackChange
{
public string Name { get; set; }
public object Original { get; set; }
public object Value { get; set; }
}
That way I can keep my Audit Log functionality on both Data Context.
When saving data using ADO.NET I will have a function that will convert my Changes into Stored Procedures parameters so I can save into my AuditLog table.
Does anyone know if this is a good alternative?
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;
}
}