This question already has answers here:
Why does Property Set throw StackOverflow exception?
(3 answers)
Closed 2 years ago.
I designed a class implementing the Builder design pattern. But creating that class using its builder, it throws System Exception that is StackOverFlow Exception. I know its builder is recursive but I only call three times its building chain. What throwing I really don't understand and it doesn't come to me logically. Below is my class that involves its own builder.
SnirgeeDosya sn = new SnirgeeDosya.SnirgeeDosyaBuilder()
.setDosyaId(0)
.setDosyaAdi("Dosya1")
.setUserId(1214)
.setDBFactory(new DatabaseFactory()).build();
public class SnirgeeDosya:ISnirgeeDosyaOracleCommands
{
public int dosyaId { set { dosyaId = value; } get { return dosyaId; } }
public int userId { set { userId = value; } get { return userId; } }
public DateTime baslangicZaman { get { return DateTime.Now; } }
public String dosyaAdi { set { dosyaAdi = value; } get { return dosyaAdi; } }
private SnirgeeOracleDBWorker oracleDbWorker{ set { oracleDbWorker = value; } get { return oracleDbWorker; } }
/// <summary>
/// SnirgeeDosya olusturması sırasında kullanılır. ilgili parametreler girildikten sonra build edilip SnirgeeDosya elde edilir. Kullanım şekli aşağıdaki gibidir.
/// SnirgeeDosya sn = new SnirgeeDosya.SnirgeeDosyaBuilder().setDosyaAdi("Dosya1").setUserId(1214).setDBFactory(new DatabaseFactory()).build();
/// </summary>
public class SnirgeeDosyaBuilder
{
public int dosyaId { set { dosyaId = value; } get { return dosyaId; } }
public int userId { set { userId = value; } get { return userId; } }
public String dosyaAdi { set { dosyaAdi = value; } get { return dosyaAdi; } }
public SnirgeeOracleDBWorker oracleDbWorker { set { oracleDbWorker = value; } get { return oracleDbWorker; } }
/// <summary>
/// Dosya Builder içerinde dosya adının belirlenmesi.
/// </summary>
/// <param name="dosyaadi"></param>
/// <returns></returns>
public SnirgeeDosyaBuilder setDosyaAdi(String dosyaadi)
{
this.dosyaAdi = dosyaadi;
return this;
}
/// <summary>
/// Dosya Builder içerinde SnirgeeDosyasının kime ait olduğunu belirten metotdur.
/// </summary>
/// <param name="userid"></param>
/// <returns></returns>
public SnirgeeDosyaBuilder setUserId(int userid)
{
this.userId = userid;
return this;
}
/// <summary>
/// Dosya Builder içerinde SnirgeeDosyasının kime ait olduğunu belirten metotdur.
/// </summary>
/// <param name="userid"></param>
/// <returns></returns>
public SnirgeeDosyaBuilder setDosyaId(int dosyaId)
{
this.dosyaId = dosyaId;
return this;
}
/// <summary>
/// Snirgee Dosyasının içerisine Veritabanı işlemleri yapan classın eklenmesi.
/// Elementlerin yazılması ve okunması sırasında bu class içerisinde kullanılacaktır.
/// </summary>
/// <param name="db"></param>
/// <returns></returns>
public SnirgeeDosyaBuilder setDBFactory(DatabaseFactory db)
{
this.oracleDbWorker = new SnirgeeOracleDBWorker(db);
return this;
}
/// <summary>
/// dosyaAdı, kullanıcıId ve Veritabanı işlerini yapacak DatabaseFactory parametreleri atandıktan sonra Snirgee Dosyasını oluşturan methodtur.
/// Henüz veritabanı SnirgeeDosya tablosuna herhangi bir kayıt atanmaz.
/// </summary>
/// <returns></returns>
public SnirgeeDosya build()
{
return new SnirgeeDosya(this);
}
}
/// <summary>
/// SnirgeeDosya'sını oluşturan SnirgeeDosyaBuilder classı build metodu içerisinde kullanılır.
/// </summary>
/// <param name="formBuilder"></param>
private SnirgeeDosya(SnirgeeDosyaBuilder formBuilder)
{
this.dosyaId = formBuilder.dosyaId;
this.userId = formBuilder.userId;
this.dosyaAdi = formBuilder.dosyaAdi;
this.oracleDbWorker = formBuilder.oracleDbWorker;
}
}
Common mistake. Your property is calling itself in the getter/setter. So when you set dosyaId, it sets dosyaId, which sets dosyaId, which sets dosyaId, which... until the call stack is full and you get a StackOverflowException.
Change
public int dosyaId { set { dosyaId = value; } get { return dosyaId; } }
to
public int dosyaId { set; get; }
And the same for the other properties. I see no need for you to have a backing field based on what you've posted. In fact, I see no need for the set... methods either - you can just set the properties directly.
It's an infinite loop - in the property, you're setting the property, which calls the property setter, which sets the property, etc. until the exception.
Either create a member variable (with a different name, this is known as a backing field) that the property sets and gets, or, since these are very simple properties, make them auto-implemented:
public int dosyaId { get; set; }
Related
Coding in C#, I am blocked on a silly JSON deserialization and hoping your expert eyes will find what I'm missing.
I am trying to extract the following JSON file:
{
"Document":
{
"Version": "1.0.0",
"LastUpdate": "10.08.2020",
"Description": "This document enumarates manufactuer capabilities",
"Id": ""
},
"Capacities": [
{
"Id": 0,
"Description": "",
"Enable": true,
"RelativePath": "Company1\\manifest.json"
},
{
"Id": 1,
"Description": "",
"Enable": true,
"RelativePath": "Company2\\manifest.json"
}
]
}
The ManifestDescriptor class should self-extract (and store) JSON data through its constructor call. The implementation is as follow:
using JsonTools;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using SessionService;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace BaseService.Manifest
{
public class ManifestDescriptor : JObject
{
/// <summary>
/// Contains Json document descriptor data
/// </summary>
private DocSection _document;
private List<Capacity> _capacity;
/// <summary>
/// Contains Json document descriptor data
/// </summary>
[JsonProperty("Document")]
public DocSection Document
{
get => _document;
set
{
if (value != _document)
{
_document = value;
}
}
}
/// <summary>
/// Contains document capacities
/// </summary>
[JsonProperty("Capacities")]
public List<Capacity> Capacities
{
get => _capacity;
internal set
{
if (value != _capacity)
{
_capacity = value;
}
}
}
public ManifestDescriptor(string absolutePath)
{
string l_rawJson = string.Empty;
if (File.Exists(absolutePath))
{
_fileInfo = new FileInfo(absolutePath);
if (!JsonParser.LoadJsonFile(absolutePath, ref l_rawJson))
{
Log.Error("Could not extract Json file data.");
return;
}
// Populate current class with manifest data
JsonConvert.PopulateObject(l_rawJson, this);
}
else Log.Warning("Given manifest file do not exist: \n\r {0}", absolutePath);
}
}
}
ManifestDescriptor contains a Document property implemented as follow:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
namespace BaseService.Manifest
{
/// <summary>
/// Class container giving Json document version & its utility
/// </summary>
public class DocSection
{
private Version _version;
private DateTime _lastUpdate;
private string _description;
private string _id;
private string _class;
/// <summary>
/// Contains document version
/// </summary>
[JsonProperty("Version")]
public Version Version
{
get => _version;
internal set
{
if (value != _version)
{
_version = value;
}
}
}
/// <summary>
/// Contains last update document version
/// </summary>
[JsonProperty("LastUpdate")]
public DateTime LastUpdate
{
get => _lastUpdate;
internal set
{
if(value != _lastUpdate)
{
_lastUpdate = value;
}
}
}
/// <summary>
/// Contains document description
/// </summary>
[JsonProperty("Description")]
public string Description
{
get => _description;
internal set
{
if(value != _description)
{
_description = value;
}
}
}
/// <summary>
/// Contains document ID
/// </summary>
[JsonProperty("Id")]
public string Id
{
get => _id;
internal set
{
if (value != _id)
{
_id = value;
}
}
}
/// <summary>
/// Object class type to instanciate regarding capacity data of the document
/// </summary>
[JsonIgnore]
[JsonProperty("Class")]
public string Class
{
get => _class;
internal set
{
if(value != _class)
{
_class = value;
}
}
}
}
}
However when reaching the line JsonConvert.PopulateObject(l_rawJson, this); called in ManifestDescriptor class constructor, I am reaching the following execption:
Cannot populate JSON object onto type
'BaseService.Manifest.ManifestDescriptor'. Path 'Document', line 2,
position 13."
May you have an idea of the issue?
Thanks for your attention,
As per #SelimYildiz, you really need to separate the population of objetc outside of the object you are trying to serialize.
If your intention is to serialize your ManifestDescriptor without knowing the process of it all you need is to past your json. Then you can create a wrapper class that will do the thing.
What is your intention of making the ManifestDescriptor inherit a JObject?
This might give you a hint, for this sample demo I didn't inherit the JObject and instead of JsonConvert.PopulateObject I used JsonConvert.Deserialized.
Wrapper Class
public class ParserWrapper<T>
where T : new()
{
private FileInfo _fileInfo;
public T ParsedObject { get; set; }
public ParserWrapper(string absolutePath)
{
string l_rawJson = string.Empty;
if (File.Exists(absolutePath))
{
_fileInfo = new FileInfo(absolutePath);
if (!JsonParser.LoadJsonFile(absolutePath, ref l_rawJson))
{
System.Diagnostics.Debug.Write("Could not extract Json file data.");
return;
}
// Populate current class with manifest data
ParsedObject = JsonConvert.DeserializeObject<T>(l_rawJson);
}
else System.Diagnostics.Debug.Write("Given manifest file do not exist: \n\r {0}", absolutePath);
}
}
ManifestorDescriptor
public class ManifestDescriptor
{
private DocSection _document;
private List<Capacity> _capacity;
[JsonProperty("Document")]
public DocSection Document
{
get => _document;
set
{
if (value != _document)
{
_document = value;
}
}
}
[JsonProperty("Capacities")]
public List<Capacity> Capacities
{
get => _capacity;
internal set
{
if (value != _capacity)
{
_capacity = value;
}
}
}
}
Implementation
var obj = new ParserWrapper<ManifestDescriptor>("json1.json");
Output:
Thanks for your attention. Combined comments help me to find out the issue. Coming back from #Rahul Sharma code answer and drawing back towards my original code, I could detect the two following issues:
Setter should not be declared as internal otherwise JsonConvert.PopulateObject(...) function will end with a nullable object.
I've set ManifestDescriptor class as child of Jobject. Removing the parent seems to resolve the raised exception I get.
The working code is then:
ManifestDescriptor class:
public class ManifestDescriptor
{
/// <summary>
/// Manifest file information field
/// </summary>
private FileInfo _fileInfo;
/// <summary>
/// Contains Json document descriptor data
/// </summary>
private DocSection _document;
private List<Capacity> _capacity;
/// <summary>
/// Manifest file information
/// </summary>
public FileInfo FileInfo
{
get => _fileInfo;
set
{
if(value != _fileInfo)
_fileInfo = value;
}
}
/// <summary>
/// Contains Json document descriptor data
/// </summary>
[JsonProperty("Document")]
public DocSection Document
{
get => _document;
set
{
if (value != _document)
{
_document = value;
}
}
}
/// <summary>
/// Contains document capacities
/// </summary>
[JsonProperty("Capacities")]
public List<Capacity> Capacities
{
get => _capacity;
internal set
{
if (value != _capacity)
{
_capacity = value;
}
}
}
public ManifestDescriptor(string absolutePath)
{
string l_rawJson = string.Empty;
if (File.Exists(absolutePath))
{
_fileInfo = new FileInfo(absolutePath);
if (!JsonParser.LoadJsonFile(absolutePath, ref l_rawJson))
{
Log.Error("Could not extract Json file data.");
return;
}
// Populate current class with manifest data
JsonConvert.PopulateObject(l_rawJson, this);
}
else Log.Warning("Given manifest file do not exist: \n\r {0}", absolutePath);
}
}
DocSection class (Document property):
/// <summary>
/// Class container giving Json document version & its utility
/// </summary>
public class DocSection
{
private Version _version;
private DateTime _lastUpdate;
private string _description;
private string _id;
private string _class;
/// <summary>
/// Contains document version
/// </summary>
[JsonProperty("Version")]
public Version Version
{
get => _version;
set
{
if (value != _version)
{
_version = value;
}
}
}
/// <summary>
/// Contains last update document version
/// </summary>
[JsonProperty("LastUpdate")]
public DateTime LastUpdate
{
get => _lastUpdate;
set
{
if(value != _lastUpdate)
{
_lastUpdate = value;
}
}
}
/// <summary>
/// Contains document description
/// </summary>
[JsonProperty("Description")]
public string Description
{
get => _description;
set
{
if(value != _description)
{
_description = value;
}
}
}
/// <summary>
/// Contains document ID
/// </summary>
[JsonProperty("Id")]
public string Id
{
get => _id;
internal set
{
if (value != _id)
{
_id = value;
}
}
}
}
I like the idea of this Agent Service that allows me to add jobs without affecting existing code, but the article is pretty old. Has something come along since 2005 that would be a better way of accomplishing the same thing?
I am limited to .Net, but I can use any version of the framework.
http://visualstudiomagazine.com/articles/2005/05/01/create-a-net-agent.aspx
Edit: Here is a summary of what I'm trying to do
Have a .Net service that can read a configuration file to dynamically load DLLs to perform tasks.
The service has a dynamic object loader that maps XML to classes in the DLLs to perform the tasks.
An example of the xml file and the class it maps is below. Basically, the service can read the Job from the xml, instantiate an instance of the CustomerAttendeeCreateNotificationWorker and call the Run() method. As a developer, I can make any number of these classes and implement whatever I want in the Run() method. Also note that the entry for "CustomerAttendanceNotificationTemplateName" gets assigned to a property with the same name on the instantiated object.
<?xml version="1.0" encoding="utf-8"?>
<Manager type="Task.RemotingManager, TaskClasses">
<Jobs type="Task.TaskJob, TaskBase" Name="CustomerAttendeeCreateNotificationWorker Worker">
<Worker type="TaskWorkers.CustomerAttendeeCreateNotificationWorker, TaskWorkers"
Description="Inserts records into NotificationQueue for CustomerAttendees"
CustomerAttendanceNotificationTemplateName ="CustomerAttendanceNotificationTemplateName"
/>
<Schedulers type="Task.FixedIntervalScheduler, TaskClasses"
DaysOfWeek="Everyday"
Frequency="00:05:00"
StartTime="00:00:00"
EndTime="23:55:00"
/>
</Jobs>
<Jobs type="Task.TaskJob, TaskBase" Name="SendNotificationWorker Worker">
<Worker type="TaskWorkers.SendNotificationWorker, TaskWorkers"
Description="Sends messages from NotificationQueue"
/>
<Schedulers type="Task.FixedIntervalScheduler, TaskClasses"
DaysOfWeek="Everyday"
Frequency="00:05:00"
StartTime="00:00:00"
EndTime="23:55:00"
/>
</Jobs>/>
</Manager>
/// <summary>
/// The customer attendee create notification worker.
/// </summary>
[Serializable]
public class CustomerAttendeeCreateNotificationWorker : TaskWorker
{
#region Constants
/// <summary>
/// The stat e_ critical.
/// </summary>
private const int StateCritical = 1;
/// <summary>
/// The stat e_ ok.
/// </summary>
private const int StateOk = 0;
#endregion
#region Fields
/// <summary>
/// The customer notification setting name.
/// </summary>
private string customerAttendanceNotificationTemplateName;
#endregion
#region Public Properties
/// <summary>
/// The customer notification setting name.
/// </summary>
public string CustomerAttendanceNotificationTemplateName
{
get
{
return this.customerAttendanceNotificationTemplateName;
}
set
{
this.customerAttendanceNotificationTemplateName = value;
}
}
/// <summary>
/// Gets or sets the logger.
/// </summary>
public ILogger Logger { get; set; }
#endregion
#region Public Methods and Operators
/// <summary>
/// The run.
/// </summary>
/// <returns>
/// The <see cref="TaskResult" />.
/// </returns>
public override TaskResult Run()
{
StringBuilder errorStringBuilder = new StringBuilder();
string errorLineTemplate = "Time: {0} Database: {1} Error Message: {2}" + Environment.NewLine;
bool isError = false;
IUnitOfWork configUnitOfWork = new GenericUnitOfWork<DCCShowConfigContext>();
TradeshowService tradeshowService = new TradeshowService(configUnitOfWork);
List<Tradeshow> tradeshows = tradeshowService.GetAll().Where(t => t.Status == "OPEN").ToList();
string connectionStringTemplate = ConfigurationManager.ConnectionStrings["DCCTradeshow"].ConnectionString;
int customerNotificationSettingGroupId = Convert.ToInt32(ConfigurationManager.AppSettings["NotificationSettingGroupId"]);
foreach (Tradeshow tradeshow in tradeshows)
{
try
{
string connectionString = string.Format(connectionStringTemplate, tradeshow.DbName);
IUnitOfWork unitOfWork = new TradeshowUnitOfWork(connectionString);
NotificationService notificationService = new NotificationService(unitOfWork);
notificationService.InsertCustomerAttendanceNotifications(tradeshow.TradeshowId, customerNotificationSettingGroupId, this.customerAttendanceNotificationTemplateName);
}
catch (Exception exception)
{
isError = true;
errorStringBuilder.AppendLine(string.Format(errorLineTemplate, DateTime.Now, tradeshow.DbName, exception.Message));
}
}
TaskResult result;
if (isError)
{
result = new TaskResult(StateOk, TaskResultStatus.Exception, "Errors Occured", errorStringBuilder.ToString());
}
else
{
result = new TaskResult(StateOk, TaskResultStatus.Ok,"All Good", "All Good");
}
return result;
}
#endregion
}`
Hello StackOverFlow users,
Iam trying to create an XSD from a dll that i created, but when i try to generate the XSD i get the following error message:
You must implement a default accessor on System.Configuration.ConfigurationLockCollection because it inherits from ICollection.
(Also tried different framework version (Did not work))
Command that gets executed:
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools>xsd "J:\
Programming\C#\NightBitsLogger Library\NightBitsLogger\bin\Debug\NightBitsLogger
.dll"
Does anyone know what i have to do to have a default accessor for the ConfigurationLockCollection?
(Because it seems that this is a bug in the .NET framework)
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Collections;
namespace NightBitsLogger.Configuration
{
/// <summary>
/// This class is an abstract class for a Collection of Config Elements
/// </summary>
/// <typeparam name="T"></typeparam>
///
[ConfigurationCollection(typeof(ConfigurationItem), AddItemName = "ConfigurationElement" )]
public abstract class CollectionOfElements<T> : ConfigurationElementCollection
where T : ConfigurationItem, new()
{
/// <summary>
/// Default Accessor for the collections
/// </summary>
[ConfigurationProperty("ConfigurationCollection", IsRequired = true)]
public CollectionOfElements<ConfigurationItem> ConfigurationCollection
{
get
{
return base["ConfigurationCollection"] as CollectionOfElements<ConfigurationItem>;
}
}
/// <summary>
/// Create and return a new Configuration Element
/// </summary>
/// <returns></returns>
protected override ConfigurationElement CreateNewElement()
{
return new T();
}
/// <summary>
/// Return the element key.
/// </summary>
/// <param name="element"></param>
/// <returns>(ConfigurationElement)key</returns>
protected override object GetElementKey(ConfigurationElement element)
{
return ((ConfigurationItem)element).Name;
}
/// <summary>
/// Return the element with the given index
/// Basic accessor for elements
/// </summary>
/// <param name="index"></param>
/// <returns>[Element]byIndex</returns>
public T this[int index]
{
get
{
return (T)BaseGet(index);
}
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
/// <summary>
/// Add a element to the collection
/// </summary>
/// <param name="collectionOfLoggerElement"></param>
public void Add(T collectionOfLoggerElement)
{
BaseAdd(collectionOfLoggerElement);
}
/// <summary>
/// Return the element with the given index
/// </summary>
/// <param name="name"></param>
/// <returns>[Element]byName</returns>
public new T this[string name]
{
get
{
return (T)BaseGet(name);
}
}
}
/// <summary>
/// The CollectionOfLoggers Collection
/// </summary>
[ConfigurationCollection(typeof(CollectionOfLoggersElement), AddItemName = "CollectionOfLoggers", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class CollectionOfLoggers : CollectionOfElements<CollectionOfLoggersElement>
{
// Do nothing
}
/// <summary>
/// The FileLogger Collection
/// </summary>
[ConfigurationCollection(typeof(FileLoggerElement), AddItemName = "fileLogger", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class FileLoggers : CollectionOfElements<FileLoggerElement>
{
// Do nothing
}
/// <summary>
/// The RollingDateFileLogger Collection
/// </summary>
[ConfigurationCollection(typeof(RollingDateFileLoggerElement), AddItemName = "rollingDateFileLogger", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class RollingDateFileLoggers : CollectionOfElements<RollingDateFileLoggerElement>
{
// Do nothing
}
/// <summary>
/// The RollingSizeFileLogger Collection
/// </summary>
[ConfigurationCollection(typeof(RollingSizeFileLoggerElement), AddItemName = "rollingSizeFileLogger", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class RollingSizeFileLoggers : CollectionOfElements<RollingSizeFileLoggerElement>
{
// Do nothing
}
/// <summary>
/// The EmailLogger Collection
/// </summary>
[ConfigurationCollection(typeof(EmailLoggerElement), AddItemName = "emailLogger", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class EmailLoggers : CollectionOfElements<EmailLoggerElement>
{
// Do nothing
}
/// <summary>
/// The SocketLogger Collection
/// </summary>
[ConfigurationCollection(typeof(SocketLoggerElement), AddItemName = "socketLogger", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class SocketLoggers : CollectionOfElements<SocketLoggerElement>
{
// Do nothing
}
/// <summary>
/// The WindowsEventLogLogger Collection
/// </summary>
[ConfigurationCollection(typeof(WindowsEventLogLoggerElement), AddItemName = "WindowsEventLogLogger", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class WindowsEventLogLoggers : CollectionOfElements<WindowsEventLogLoggerElement>
{
// Do nothing
}
/// <summary>
/// The ConsoleLogger Collection
/// </summary>
[ConfigurationCollection(typeof(ConsoleLoggerElement), AddItemName = "consoleLogger", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class ConsoleLoggers : CollectionOfElements<ConsoleLoggerElement>
{
// Do nothing
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.ComponentModel;
namespace NightBitsLogger.Configuration
{
/// <summary>
/// This is the baseClass that represents a Config Item (Logger)
/// </summary>
public class ConfigurationItem : ConfigurationSection
{
/// <summary>
/// Get the configuration
/// </summary>
/// <returns></returns>
public static ConfigurationItem GetConfiguration()
{
ConfigurationItem configuration = ConfigurationManager.GetSection("NightBitsLogger.Configuration") as ConfigurationItem;
if (configuration != null)
{
return configuration;
}
return new ConfigurationItem();
}
/// <summary>
/// Occurs after the element is deserialized
/// </summary>
///
protected override void PostDeserialize()
{
base.PostDeserialize();
Validate();
}
/// <summary>
/// Validate the element. Throw a exception if not valid.
/// </summary>
protected virtual void Validate()
{
if ((IncludeCategories.Trim() != "") && (ExcludeCategories.Trim() != ""))
{
throw new ConfigurationErrorsException("logging element can have either includeCategories or excludeCategories, but not both.");
}
}
/// <summary>
/// Return true if the Logger Element is configured for the current machine; otherwise return false.
/// </summary>
/// <returns></returns>
public bool IsConfiguredForThisMachine()
{
var machineNames = Machine.Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return (machineNames.Length == 0) || new List<string>(machineNames).Exists(name => name.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase));
}
/// <summary>
/// Get the name of the Logger
/// </summary>
[ConfigurationProperty("name", DefaultValue = "", IsKey = true, IsRequired = true)]
[Description("The name of the logger")]
public string Name
{
get
{
return (string)this["name"];
}
}
/// <summary>
/// The machine names (separated by commas) for which the Logger will be created. An empty value creates it on all machines.
/// </summary>
[ConfigurationProperty("machine", DefaultValue = "", IsRequired = false)]
[Description("The machine names (separated by commas) for which this logger will be created. Leaving it empty will create it on all machines")]
public string Machine
{
get
{
return (string)this["machine"];
}
}
/// <summary>
/// Check if the Internal Exception Logging is enabled
/// </summary>
[ConfigurationProperty("enableInternalExceptionLogging", DefaultValue = false, IsRequired = false)]
[Description("true if the internal exceptionLogging is enabled; otherwise false")]
public bool IsInternalLoggingEnabled
{
get
{
return (bool)this["isInternalLoggingEnabled"];
}
}
/// <summary>
/// Check if the Logger is enabled
/// </summary>
[ConfigurationProperty("isEnabled", DefaultValue = true, IsRequired = false)]
[Description("true if the logger is enabled; otherwise false")]
public bool IsEnabled
{
get
{
return (bool)this["isEnabled"];
}
}
/// <summary>
/// The LogLevel of the Logger
/// </summary>
[ConfigurationProperty("logLevel", DefaultValue = LogLevel.Debug, IsRequired = false)]
[Description("The logLevel of the logger")]
public LogLevel LogLevel
{
get
{
return (LogLevel)this["logLevel"];
}
}
/// <summary>
/// Categories to include (leave blank for all)
/// </summary>
[ConfigurationProperty("includeCategories", DefaultValue = "", IsRequired = false)]
[Description("The categories, separated by commas, to include when logging. Leave blank to include everything.")]
public string IncludeCategories
{
get
{
return (string)this["includeCategories"];
}
}
/// <summary>
/// Categories to exclude
/// </summary>
[ConfigurationProperty("excludeCategories", DefaultValue = "", IsRequired = false)]
[Description("The categories, separated by commas, to exclude when logging.")]
public string ExcludeCategories
{
get
{
return (string)this["excludeCategories"];
}
}
/// <summary>
/// If true, wrap the Logger in an KeepLoggingLogger.
/// </summary>
[ConfigurationProperty("keepLogging", DefaultValue = false, IsRequired = false)]
[Description("if true, the logger will be wrapped in a KeepLoggingLogger")]
public bool keepLogging
{
get
{
return (bool)this["keepLogging"];
}
}
/// <summary>
/// If true, wrap the Logger in an AsynchronousLogger.
/// </summary>
[ConfigurationProperty("isAsynchronous", DefaultValue = false, IsRequired = false)]
[Description("if true, the logger will be wrapped in a AsynchronousLogger")]
public bool IsAsynchronous
{
get
{
return (bool)this["isAsynchronous"];
}
}
/// <summary>
/// The FormatString for the Logger
/// </summary>
[ConfigurationProperty("formatString", DefaultValue = "", IsRequired = false)]
[Description("The format string of the logger. If blank, it will use the format string of the enclosing section (the CollectionOfLoggers).")]
public virtual string FormatString
{
get
{
return (string)this["formatString"];
}
}
}
}
I'm busy creating an assembly that will gather CodeModel information wich in turn is used to generate code with a T4 template.
I'm struggling with CodeModel because of the lack of good information. I found a few books describing the CodeModel but only the true basics. Found no in-depth documentation.
The past week I created the mentioned assembly and the following construct worked fine for over 4 days.
/// <summary>
/// The CodeType of the property
/// </summary>
public CodeType CodeType
{
get
{
if (!m_CodeTypeInitialized)
{
CodeTypeRef codeTypeRef = CodeProperty.Type;
m_CodeType = codeTypeRef.CodeType;
m_CodeTypeInitialized = true;
}
return m_CodeType;
}
}
Yesterday suddenly this construct no longer returns the CodeType anymore. I've now changed the code to this
/// <summary>
/// The CodeType of the property
/// </summary>
public CodeType CodeType
{
get
{
if (!m_CodeTypeInitialized)
{
if (CodeProperty.IsCodeType)
{
CodeTypeRef codeTypeRef = CodeProperty.Type;
m_CodeType = codeTypeRef.CodeType;
}
m_CodeTypeInitialized = true;
}
return m_CodeType;
}
}
This no longer causes an exception but the outcome is always 'null'. I'm lost. What could cause the CodeProperty to, all of a sudden, loose it's CodeType?
I really need the CodeType because a lot of code is hinging on it's information.
I was able to create a work arround like this. It's not nice but it works fine:
private FileCodeModel m_FileCodeModel;
/// <summary>
/// The FileCodeModel the entity of this property is found in.
/// </summary>
public FileCodeModel FileCodeModel
{
get
{
if (m_FileCodeModel == null)
{
m_FileCodeModel = EntityMetadata.FileCodeModel;
}
return m_FileCodeModel;
}
}
private Project m_Project;
/// <summary>
/// The project this properties entity is contained in.
/// </summary>
public Project ContainingProject
{
get
{
if (m_Project == null)
{
m_Project = FileCodeModel.Parent.ContainingProject;
}
return m_Project;
}
}
private CodeModel m_CodeModel;
/// <summary>
/// The CodeModel for the properties entity.
/// </summary>
public CodeModel CodeModel
{
get
{
if (m_CodeModel == null)
{
m_CodeModel = ContainingProject.CodeModel;
}
return m_CodeModel;
}
}
/// <summary>
/// De CodeType van de property
/// </summary>
public CodeType CodeType
{
get
{
if (!m_CodeTypeInitialized)
{
if (CodeProperty.IsCodeType)
{
CodeTypeRef codeTypeRef = CodeProperty.Type;
m_CodeType = codeTypeRef.CodeType;
}
else
{
m_CodeType = CodeModel.CodeTypeFromFullName(CodeProperty.Type.AsFullName);
}
m_CodeTypeInitialized = true;
}
return m_CodeType;
}
}
I am confused about why I am receiving "Ninject.ActivationException : Error Activating string No matching bindings are available, and the type is not self-bindable" in random bindings. If I leave the binding for IMedia in place it will throw the ActivationException, but if I use the CallbackProvider it works. All of these classes are structured the same with a few different properties. I'm confused as to why ILocationType, IMedia, and IFarmDataContext throw ActivationException while the others do not. Any ideas?
/******************************
* Core Types
******************************/
Bind<IFarmDataContext>().ToProvider(new CallbackProvider<IFarmDataContext>(delegate { return new FarmDataContext(); }));
//Media
Bind<IMedia>().To<Media>(); //blows up
//Bind<IMedia>().ToProvider(new CallbackProvider<IMedia>(delegate { return new Media(); }));
Bind<IMediaType>().To<MediaType>();
Bind<IMediaRelated>().To<MediaRelated>();
//Location
Bind<ILocation>().To<Location>();
Bind<ILocationType>().ToProvider(new CallbackProvider<ILocationType>(delegate { return new LocationType(); }));
Bind<ILocationDetail>().To<LocationDetail>();
Ninject doesn't have a binding for the "String key" to inject in the Media .ctor; When it tries to create a type that depends on Media, it doesn't know how to resolve the dependency and throws. For most types, Ninject would try to create something for you, but string and value types are not self-bindable as we don't have a good default value for them and it can cause havoc on types that use different conventions with primitives.
You need add a parameter value in your bindings (.WithContructorArgument("key", someValue)) or use some kind of provider (which you have done).
Below are the IMedia interface and Media implementation. Media is a partial class with the primary class generated via a LinqToSql DBML file. This is the case for all of the types listed above in the list of bindings.
public interface IMedia : IValidationDictionary, IBaseDescriptor {
/// <summary>
/// Returns a specific Media object specifying
/// if you want the full or lite version
/// </summary>
/// <param name="id"></param>
/// <param name="isLite"></param>
/// <param name="context"></param>
/// <returns></returns>
IMedia Get(long id, bool isLite, DataContext context);
/// <summary>
/// Returns the lite version of the request Media object
/// </summary>
/// <param name="id"></param>
/// <param name="context"></param>
/// <returns></returns>
IMedia Get(long id, DataContext context);
/// <summary>
/// Returns a list of Media Objects
/// </summary>
/// <param name="isLite"></param>
/// <param name="context"></param>
/// <returns></returns>
ValidationList<IMedia> List(bool isLite, DataContext context);
/// <summary>
/// Returns a list of Media Objects with pagination capabilities
/// </summary>
/// <param name="isLite"></param>
/// <param name="skip"></param>
/// <param name="top"></param>
/// <param name="context"></param>
/// <returns></returns>
ValidationList<IMedia> List(bool isLite, int skip, int top, DataContext context);
}
public partial class Media : BaseDescriptor, IMedia {
#region Constructors
public Media(String key, IError error)
: base() {
AddError(key, error);
}
#endregion
#region Properties
public MediaType Type {
set { if (TypeID <= 0) { MediaType = value; } }
get { return MediaType; }
}
#endregion
#region Internal Methods
/// <summary>
/// Truncates relationships as appropriate to reduce over-the-wire size
/// </summary>
protected override void MakeLite() {
MediaRelateds = new EntitySet<MediaRelated>();
}
/// <summary>
/// Validates the values and returns true if there are no problems.
/// </summary>
override public bool Validate() {
this.ClearErrors();
if (this.TypeID <= 0) { this.AddError("TypeID", new Error(ErrorType.VALIDATION, "TypeID is missing or invalid")); }
if (string.IsNullOrEmpty(this.Path)) { this.AddError("Path", new Error(ErrorType.VALIDATION, "Path is missing or invalid")); }
if (this.CreatedOn.Year <= 1900) { this.AddError("CreatedOn", new Error(ErrorType.VALIDATION, "CreatedOn is missing or invalid")); }
if (this.CreatedBy <= 0) { this.AddError("CreatedBy", new Error(ErrorType.VALIDATION, "CreatedBy is missing or invalid")); }
if (this.UpdatedOn.Year <= 1900) { this.AddError("UpdatedOn", new Error(ErrorType.VALIDATION, "UpdatedOn is missing or invalid")); }
if (this.UpdatedBy <= 0) { this.AddError("UpdatedBy", new Error(ErrorType.VALIDATION, "UpdatedBy is missing or invalid")); }
if (!string.IsNullOrEmpty(this.Path) && this.Path.Length > 255) { this.AddError("Path", new Error(ErrorType.VALIDATION, "Path is longer than the maximum of 255 characters")); }
return (this.ErrorCount == 0);
}
#endregion
#region Public Methods
public ValidationList<IMedia> List(bool isLite, DataContext context) {
return List(isLite, 0, 0, context);
}
public ValidationList<IMedia> List(bool isLite, int skip, int top, DataContext context) {
if (context == null) { context = new DataContext(); }
var query = context.Medias.Where(x => x.DeletedOn == null);
List<Media> results;
if (skip > 0 || top > 0) {
if (top > 0) {
if (skip < 0) { skip = 0; }
results = query.OrderBy(x => x.ID).Skip(skip).Take(top).ToList();
} else {
results = query.OrderBy(x => x.ID).Skip(skip).ToList();
}
} else {
results = query.OrderBy(x => x.ID).ToList();
}
var finalResult = new ValidationList<IMedia>(new List<IMedia>());
foreach (var result in results) {
result.IsLite = isLite;
finalResult.Source.Add(result);
}
return finalResult;
}
public IMedia Get(long id, DataContext context) {
return Get(id, false, context);
}
public IMedia Get(long id, bool isLite, DataContext context) {
if (context == null) { context = new DataContext(); }
var results = context.Medias.Where(x => x.ID == id && x.DeletedOn == null).ToList();
var result = (results.Count > 0 ? results[0] : null);
if (result != null) {
result.IsLite = isLite;
}
return result;
}
#endregion
}