I try to write this class:
public class ModelManager
{
public OmniacareHomeProductionEntities _db;
public CategoriaManager categoriaManager
{
get { return categoriaManager; }
set
{
if (categoriaManager == null)
{
categoriaManager = new CategoriaManagerImpl();
}
}
}
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(ModelManager));
public ModelManager()
{
_db = new OmniacareHomeProductionEntities();
}
}
CategoriaManager is an Interface and CategoriaManagerImpl is a class that implements CategoriaManager.
I use ModelManager class in this mode:
ModelManager modelManager = new ModelManager();
modelManager.categoriaManager.saveLocalCategory(category, true);
so when I try to run this code, I have a StackOverflowError at this line
get
{
return categoriaManager;
}
Where is my error? Can you help me?
Your problem is clearly here
public CategoriaManager categoriaManager
{
get
{
return categoriaManager;
}
set
{
if (categoriaManager == null)
{
categoriaManager = new CategoriaManagerImpl(); //HERE !!!!!!!!!
}
}
}
the name of the member is the same of the property, change it like this, for example:
public CategoriaManager CatManager //NAME OF HE PROPERTY ISCHANGED !!!!
{
get
{
return categoriaManager;
}
set
{
if (categoriaManager == null)
{
categoriaManager = new CategoriaManagerImpl();
}
}
}
General guideline:
for properties use names starting from upper case
for fields use names starting from low case
So your code would lool like this:
ModelManager modelManager = new ModelManager();
modelManager.CatManager.saveLocalCategory(category, true);
You should change it like this:
private CategoriaManager _categoriaManager;
public CategoriaManager CategoriaManager
{
get { return _categoriaManager; }
set
{
if (_categoriaManager == null)
{
_categoriaManager = new CategoriaManagerImpl();
}
}
}
Related
I have a public method ValidateWords inside FooService.To test the ValidateWord method, I created IAppSettingWrapper and AppSettingWrapper which returns the Instance of AppSettings.
Inside the test method, I want to substitute NotAllowedWords using NSubstitute. However, it throws an object reference exception. Is there any way for substitution? If it's not possible, how can I refactor my static instance?
public sealed class AppSettings
{
private static object _lockObject = new object();
private static volatile AppSettings? _instance;
private static DateTime _cacheTime;
private Settings[] _settings;
public AppSettings()
{
try
{
_settings = GetSettings();
}
catch { }
}
public static AppSettings Instance
{
get
{
lock (_lockObject)
{
if (_instance == null)
{
_instance = new AppSettings();
}
}
return _instance;
}
}
public List<string> NotAllowedWords
{
get
{
return new List<string>() {
"index",
"change"
};
}
}
public T GetValues<T>(string key,T defaultValue)
{
T result = defaultValue;
var settings = _settings.Where(i => i.Key == key).FirstOrDefault();
result = (T)Convert.ChangeType(settings.Value, typeof(T));
return result;
}
private Settings[]? GetSettings()
{
//gets data from web services
return base.Channel.GetSettings();
}
}
public class Settings
{
public string Key { get; set; }
public string Value { get; set; }
}
public interface IAppSettingsWrapper
{
public AppSettings Instance();
}
public class AppSettingsWrapper : IAppSettingsWrapper
{
public AppSettings Instance()
{
return AppSettings.Instance;
}
}
[TestClass]
public class FooServiceTest{
private IAppSettingsWrapper _appSettingsWrapper;
[TestInitialize]
public void TestInitialize(IAppSettingsWrapper appSettingsWrapper)
{
_appSettingsWrapper = Substitute.For<IAppSettingsWrapper>();
}
private FooService CreateFooService()
{
return new FooService(_appSettingsWrapper);
}
[TestMethod]
public void Throw_Exception_When_Given_Word_Not_Allowed() {
var service = this.CreateFooService();
_appSettingsWrapper.Instance().NotAllowedWords.Returns(new List<string> { "index" });
var word = "index";
Exception ex = Assert.ThrowsException<Exception>(() => service.ValidateWords(word));
Assert.AreEqual("this word is not allowed", ex.Message);
}
}
public class FooService
{
private IAppSettingsWrapper _appSettingsWrapper;
public FooService(IAppSettingsWrapper appSettingsWrapper)
{
_appSettingsWrapper = appSettingsWrapper;
}
public void ValidateWords(string word)
{
if (_appSettingsWrapper.Instance().NotAllowedWords.Contains(word))
{
throw new Exception("this word is not allowed");
}
}
}
The AppSettings.NotAllowedWords property is not substitutable due to it not being virtual and the class being sealed. If you add NSubstitute.Analyzers to your test project it will help you find these cases. (The How NSubstitute Works documentation outlines why this is the case.)
One option is to make AppSettings implement an IAppSettings interface and inject that into FooService (rather than the wrapper). Then you can use a substitute for tests, and AppSettings.Instance for your real code.
can I call my property TaskAll from the method Task
My code is
private ObservableCollection<TaskExecutionHistoryModel> _TaskAll;
public ObservableCollection<TaskExecutionHistoryModel> TaskAll
{
get{ return _TaskAll;}
set
{
_TaskAll = value;
base.NotifyPropertyChanged(x => x.TaskAll);
}
}
public Task(ObservableCollection<TaskExecutionHistoryModel> ExecutionHistory)
{
}
Yes.
public Task(ObservableCollection<TaskExecutionHistoryModel> ExecutionHistory)
{
ObservationCollection<TaskExecutionHistoryModel> model = TaskAll;
}
Yes you can by simply calling it:
public Task(ObservableCollection<TaskExecutionHistoryModel> ExecutionHistory)
{
TaskAll = someValue;
someOtherValue = TaskAll;
}
I might have coded myself into a corner here, but I am hoping there is a simple way out of it.
My Logic Layer is a static singleton instance that has lots of properties for accessing the individual sub-Logic Layers. Most of this was put in place for unit testing to allow injection of custom repositories and works quite nicely for that. However the boiler plate code for each sub-instance is very repetitive and I would expect that there is a way to simplify it.
Below is a very simplified example to demonstrate how far I have manages to get and where I am stuck. The one way that works is with an indexer on the sub-logic class wrapper to get to the sub-logic, which reads very strangely. The other way is by using a random letter as a property on the sub-logic class wrapper to get to the sub-logic. This reads slightly better, but still has a ripple effect on all the existing code.
Can this be done the way I want to, or should I be looking at this completely differently.
Apologies for the length of the example. I tried to make it as simple as possible while still keeping the concept intact
class Program
{
static void Main(string[] args)
{
var logic = new Logic();
// old usage (desired)
var abcs_1 = logic.ABCs_1.List();
var defs_1 = logic.DEFs_1.List();
// new usage (would like to keep old way)
var abcs_2 = logic.ABCs_2[0].List(); // <-- ugly
var defs_2 = logic.DEFs_2.d.List(); // <-- less ugly, but still not pretty
//var abcs_2 = logic.ABCs_2.List(); // <-- wanted
//var defs_2 = logic.DEFs_2.List(); // <-- wanted
}
}
public class ABC { }
public class DEF { }
public class ABCsLogicLayer
{
public List<ABC> List() { return null; }
}
public class DEFsLogicLayer
{
public List<DEF> List() { return null; }
}
public class Logic
{
#region New Code. Want to move towards this
public LogicLocker<ABCsLogicLayer> ABCs_2 = new LogicLocker<ABCsLogicLayer>();
public LogicLocker<DEFsLogicLayer> DEFs_2 = new LogicLocker<DEFsLogicLayer>();
#endregion
#region Old Code. Want to move away from this.
#region BuilerPlate for ABCs_1
private ABCsLogicLayer m_ABCs = null;
private readonly object m_ABCsLock = new object();
public ABCsLogicLayer ABCs_1
{
get
{
lock (m_ABCsLock)
{
if (m_ABCs == null)
{
m_ABCs = new ABCsLogicLayer();
}
}
return m_ABCs;
}
set
{
lock (m_ABCsLock)
{
m_ABCs = value;
}
}
}
#endregion
#region BuilerPlate for DEFs_1
private DEFsLogicLayer m_DEFs = null;
private readonly object m_DEFsLock = new object();
public DEFsLogicLayer DEFs_1
{
get
{
lock (m_DEFsLock)
{
if (m_DEFs == null)
{
m_DEFs = new DEFsLogicLayer();
}
}
return m_DEFs;
}
set
{
lock (m_DEFsLock)
{
m_DEFs = value;
}
}
}
#endregion
#endregion
}
public class LogicLocker<T> where T : class, new()
{
private T LogicLayer = null;
private readonly object LogicLayerLock = new object();
public T this[int i]
{
get
{
lock (LogicLayerLock)
{
if (LogicLayer == null)
{
LogicLayer = new T();
}
}
return LogicLayer;
}
set
{
lock (LogicLayerLock)
{
LogicLayer = value;
}
}
}
public T d
{
get
{
lock (LogicLayerLock)
{
if (LogicLayer == null)
{
LogicLayer = new T();
}
}
return LogicLayer;
}
set
{
lock (LogicLayerLock)
{
LogicLayer = value;
}
}
}
}
You can use interface for solve your problem:
1) Define interface with List method:
public interface ILogicLayer<T>
{
List<T> List();
}
2) Your logic layer class should implement this interface:
public class ABCsLogicLayer:ILogicLayer<ABC>
3) LogicLocker should implement this interface as well
public class LogicLocker<T,U> : ILogicLayer<U> where T : ILogicLayer<U>, new()
Implementation of List method will be:
lock (LogicLayerLock)
{
if (LogicLayer == null)
{
LogicLayer = new T();
}
}
return LogicLayer.List();
4) You will instantiate your logic locker in the Logic class
public LogicLocker<ABCsLogicLayer, ABC> ABCs_2 = new LogicLocker<ABCsLogicLayer,ABC>();
public LogicLocker<DEFsLogicLayer, DEF> DEFs_2 = new LogicLocker<DEFsLogicLayer, DEF>();
or better make it more generics:
public LogicLocker<LogicLayer<ABC>> ABCs_2 = new LogicLocker<LogicLayer<ABC>>();
but it depends on what you want
The question is rather about serialized generic list<>
I have used a tool xsd2code for generating a serialized class file from xml schema to generate xml file on given data.
The class file contains all the xml data fields variables into classes as bellow-
public partial class Awmds
{
private List bol_segmentField;
public Awmds()
{
this.bol_segmentField = new List<AwmdsBol_segment>();
}
public List<AwmdsBol_segment> Bol_segment
{
get
{
return this.bol_segmentField;
}
set
{
this.bol_segmentField = value;
}
}
}
public partial class AwmdsBol_segment
{
private AwmdsBol_segmentBol_id bol_idField;
private sbyte consolidated_CargoField;
private AwmdsBol_segmentLoad_unload_place load_unload_placeField;
private AwmdsBol_segmentTraders_segment traders_segmentField;
private List<AwmdsBol_segmentCtn_segment> ctn_segmentField;
private AwmdsBol_segmentGoods_segment goods_segmentField;
private string value_segmentField;
public AwmdsBol_segment()
{
this.goods_segmentField = new AwmdsBol_segmentGoods_segment();
this.ctn_segmentField = new List<AwmdsBol_segmentCtn_segment>();
this.traders_segmentField = new AwmdsBol_segmentTraders_segment();
this.load_unload_placeField = new AwmdsBol_segmentLoad_unload_place();
this.bol_idField = new AwmdsBol_segmentBol_id();
}
public AwmdsBol_segmentBol_id Bol_id
{
get
{
return this.bol_idField;
}
set
{
this.bol_idField = value;
}
}
public sbyte Consolidated_Cargo
{
get
{
return this.consolidated_CargoField;
}
set
{
this.consolidated_CargoField = value;
}
}
.... and so on for other fields ....
}
public partial class AwmdsBol_segmentBol_id
{
private string bol_referenceField;
private sbyte line_numberField;
private sbyte bol_natureField;
private string bol_type_codeField;
public string Bol_reference
{
get
{
return this.bol_referenceField;
}
set
{
this.bol_referenceField = value;
}
}
public sbyte Line_number
{
get
{
return this.line_numberField;
}
set
{
this.line_numberField = value;
}
}
public sbyte Bol_nature
{
get
{
return this.bol_natureField;
}
set
{
this.bol_natureField = value;
}
}
public string Bol_type_code
{
get
{
return this.bol_type_codeField;
}
set
{
this.bol_type_codeField = value;
}
}
}
.... and so on for other classes ....
I have all the data to fill the generic list: List bol_segmentField
My problem is I dont know how to insert the data to the members of List bol_segmentField based on the class file.
Someone please help me to fillup the generic list by the class variables.
Maybe I am missing something, but would this work:
var awds = new Awmds();
var segment = new AwmdsBol_segment();
// here fill in the segment
awds.Bol_segment.Add(segment);
I am trying to modify an object after its creation. I would like to set the properties of this object to -1 for int or string.empty "" for a string. Bellow is a sample code of what I already have.
class TestClassAccess{
public int MyPropInt { get; set { ModifyOnAccessDenied<int>(value); } }
public string MyPropString { get; set { ModifyOnAccessDenied<string>(value); } }
public TestClassAccess() { }
private T ModifyOnAccessDenied<T>(T propertyToChange) {
var _hasAccess = false; //not really important how this is made
if (!_hasAccess)
{
if (propertyToChange is string)
propertyToChange = string.Empty;
else if (propertyToChange is int)
propertyToChange = -1;
}
return propertyToChange;
}
}
so.. issues i am having.
It doesn't compile as I cannot convert property to change to string or int.
I don't knot if i can use set methods like this.
Is this possible or am i being to ambitious.
Thank.s
KJ
If you are checking for specific types in a generic function you are probably doing something wrong. In this case you can easily just pass in a default value rather than having it hard coded:
private T ModifyOnAccessDenied<T>(T newValue, T defaultValue) {
var _hasAccess = false; //not really important how this is made
if (!_hasAccess)
{
newValue = defaultValue;
}
return newValue;
}
I've also renamed propertyToChange to newValue because what you have in this function is the new value, not a property.
Also your property definitions will not work. If you need to include any logic in your getter or setting you cannot use the auto-initializer syntax and must implement the property with a backing field.
There doesn't seem to be a point in making this function generic if it needs specific action for each type. This seems more appropriate.
class TestClassAccess
{
public int MyPropInt { get; set { ModifyOnAccessDenied<int>(value); } }
public string MyPropString { get; set { ModifyOnAccessDenied<string>(value); } }
public TestClassAccess() { }
private static volatile bool _hasAccess = false;
private string ModifyOnAccessDenied<string>(string propertyToChange)
{
if (!_hasAccess)
return string.Empty;
return propertyToChange;
}
private int ModifyOnAccessDenied<int>(int propertyToChange)
{
if (!_hasAccess)
return -1;
return propertyToChange;
}
}
You can however do this using dynamics, but this does require .NET 4.0
private T ModifyOnAccessDenied<T>(T propertyToChange)
{
if (!_hasAccess)
{
if (propertyToChange is string)
return (dynamic)string.Empty;
else if (propertyToChange is int)
return (dynamic)(int)-1;
}
return propertyToChange;
}
Fully working sample:
static class Program
{
[STAThread]
static void Main()
{
TestClassAccess test = new TestClassAccess();
test.MyPropInt = 4;
test.MyPropString = "TEST";
Console.WriteLine("MyPropInt {0}, MyPropString '{1}'",test.MyPropInt, test.MyPropString);
// Prints "MyPropInt -1, MyPropString ''
}
class TestClassAccess
{
private int myPropInt = 0;
public int MyPropInt { get { return myPropInt; } set { myPropInt = ModifyOnAccessDenied<int>(value); } }
private string myPropString = string.Empty;
public string MyPropString { get { return myPropString; } set { myPropString = ModifyOnAccessDenied<string>(value); } }
public static volatile bool _hasAccess = false;
private T ModifyOnAccessDenied<T>(T propertyToChange)
{
if (!_hasAccess)
{
if (propertyToChange is string)
return (dynamic)string.Empty;
else if (propertyToChange is int)
return (dynamic)(int)-1;
}
return propertyToChange;
}
}
}