У меня проблема с некоторыми сборками в моем анализе FxCop.
Большинство сборок из нашего проекта работают нормально, за исключением тех, которые для Api. FxCop просто прекращает анализировать их после 135 сообщений с исключением.
Это детали исключения, которые я получаю.
При чтении модуля произошла следующая ошибка
'TenForce.Execution.Api2.Implementation': не удалось разрешить член
ссылка: [TenForce.Execution.Api2.Implementation, Version = 1.0.0.0,
Culture = нейтрально,
PublicKeyToken = нуль] TenForce.Execution.Api2.Implementation.Helpers.IdGenerator 1<type
parameter.T>+Wrapper
1 :: Object.
Я позаботился о том, чтобы все необходимые сборки были вместе и являются частью проекта, но я не знаю, как решить эту проблему.
Кто-нибудь сталкивался с этим раньше?
- FxCop 10.0
- Visual Studio 2010
- .NET Framework 4
- TeamCity Test Server
EDIT
Добавление исходного кода для класса, вызывающего проблему:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Collections.ObjectModel;
namespace TenForce.Execution.Api2.Implementation.Helpers
{
/// <summary>
/// <para>This class is responsible for generating the various Ids for the Ts.</para>
/// </summary>
public static class IdGenerator<T> where T : class, IEquatable<T>, new()
{
/// <summary>
/// Wraps underlying object. Requires object to have int Id property.
/// </summary>
/// <typeparam name="T"></typeparam>
public class Wrapper<T> : IEquatable<Wrapper<T>>
{
private PropertyInfo piId;
/// <summary>
/// Wrapper constructor
/// </summary>
/// <param name="instance"></param>
public Wrapper(T instance)
{
Object = instance;
Created = DateTime.Now;
foreach (var pi in instance.GetType().GetProperties())
{
if (pi.Name.Equals("id", StringComparison.OrdinalIgnoreCase))
{
piId = pi;
}
}
if (piId == null)
{
var fullName = instance.GetType().FullName;
throw new TypeInitializationException(fullName,
new Exception(string.Format("{0} is not compatible with IdGenerator. It requires int Id property to be present", fullName)));
}
}
/// <summary>
/// Gets or sets wrapped instance Id
/// </summary>
public int Id
{
get
{
return (int)piId.GetValue(Object, null);
}
set
{
piId.SetValue(Object, value, null);
}
}
/// <summary>
/// Creation date
/// </summary>
public DateTime Created;
/// <summary>
/// Wrapped instance
/// </summary>
public T Object;
/// <summary>
/// Implements IEquatable interface
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
public bool Equals(Wrapper<T> other)
{
return Object.Equals(other.Object);
}
}
#region Private Fields
private static Wrapper<T>[] _mWrappers = new Wrapper<T>[10];
private static readonly object MPadLock = new object();
#endregion
#region Public Members
/// <summary>
/// <para>Generates a new Id for the T and assigns it to the T.</para>
/// </summary>
/// <param name="obj">The T that needs a new Id generated.</param>
/// <remarks>The T will be stored inside the generator to keep track of the Id and availability.</remarks>
public static void GenerateId(T obj)
{
lock (MPadLock)
{
// Search the array for an empty spot or an expired T.
int index = Array.FindIndex(_mWrappers, s => s == null || DateTime.Now.Subtract(s.Created).Minutes > 10);
var wrapper = new Wrapper<T>(obj);
// If we found such a spot, store the new T in that location,
// If we did not find such a spot, expand the array and the T at the end.
if (index > -1) _mWrappers[index] = wrapper;
else
{
Array.Resize(ref _mWrappers, _mWrappers.Length + 1);
_mWrappers[_mWrappers.Length - 1] = wrapper;
}
// Always update the Id of the T entity with the negative index of the entity's location.
wrapper.Id = CalculateId(Array.IndexOf(_mWrappers, wrapper));
}
}
/// <summary>
/// <para>Releases the Id generated for the T and releases the location that was held by the T.</para>
/// </summary>
/// <param name="obj">The T that needs to be released.</param>
/// <remarks>The T will be removed from the generator and it's Id will be reset to zero !!!</remarks>
public static void ReleaseId(T obj)
{
lock (MPadLock)
{
var wrapper = new Wrapper<T>(obj);
if (wrapper.Id >= 0) return;
int index = Array.IndexOf(_mWrappers, wrapper);
Array.Clear(_mWrappers, index, 1);
wrapper.Id = 0;
}
}
/// <summary>
/// <para>Fetches the specified T from the IdGenerator.</para>
/// </summary>
/// <param name="id">The unique identifier of the T.</param>
/// <returns>The T with the matching Id or the default instance if not found.</returns>
public static T Fetch(int id)
{
lock (MPadLock)
{
var found = Array.Find(_mWrappers, s => s != null && s.Id == id);
return found == null ? new T() : found.Object;
}
}
/// <summary>
/// <para>Updates the matching T entity inside the Generator with the new one.</para>
/// </summary>
/// <param name="obj">The T that needs to be updated.</param>
public static void Update(T obj)
{
lock (MPadLock)
{
int index = Array.IndexOf(_mWrappers, obj);
if (index == -1) return;
var wrapped = new Wrapper<T>(obj);
_mWrappers[index] = wrapped;
wrapped.Id = CalculateId(index);
wrapped.Created = DateTime.Now;
}
}
/// <summary>
/// <para>Retrieves all the Ts currently available in the application.</para>
/// </summary>
/// <returns>An enumerable collection containing all the T entities.</returns>
public static IEnumerable<T> ListAll()
{
lock (MPadLock)
{
return new ReadOnlyCollection<T>(_mWrappers.Select(s => s == null ? null : s.Object).Where(o => o != null).ToList());
}
}
#endregion
#region Private Members
/// <summary>
/// <para>Calculates the negative id for an entity based upon the zero-based index.</para>
/// </summary>
/// <param name="index">The zero-based index of the entity who's Id needs to be calculated.</param>
/// <returns>The new Id for the entity.</returns>
private static int CalculateId(int index)
{
return (index * -1) - 1;
}
#endregion
}
}