C# reuse method and avoid disposing on using - c#

I would like to optionally dispose (with a using statement) an object. If the connection string is passed in the constructor, then the using must dispose and if the object SQLDataLayer is passed in the constructor, then I don't want to dispose. This is to avoid passing the SQLDataLayer object in every re-usable method, is this the right approach?
public class RepoCategory
{
readonly string connString;
SQLDataLayer dl = null;
public RepoCategory(string conn_string)
{
this.connString = conn_string;
}
public RepoCategory(SQLDataLayer dl)
{
this.dl = dl;
}
//I WANT TO MAGICALLY generate using(null) if dl was passed in constructor
//or using(dl = new SQLDataLayer(connString)) if connString was passed.
public Category Get(int category_sid)
{
Category cat = null;
using (SQLDataLayer dlDispose = (dl == null) ? new SQLDataLayer(connString) : null)
{
//can this be simplified/avoided?
if (dlDispose != null)
dl = dlDispose;
cat = dl.GetCat();
}
return cat;
}
//I DON'T WANT TO PASS THE DL MANUALLY EVERYTIME
public Category Get(SQLDataLayer dl, int category_sid)
{
Category cat = null;
cat = dl.GetCat();
return cat;
}
}
thanks!

using is just short hand for
try
{
obj = new Obj();
}
finally
{
obj.Dispose();
}
You can call Dispose directly if you want. Just do try / finally and in the finally go if(xxx) obj.Dispose()

You don't need to declare variables in a using statement.
You can make a using statement that only does anything in some circumstances:
SQLDataLayer dl = ...;
using(someCondition ? dl : null) {
...
}

In your particular example, like this:
SQLDataLayer dlDispose = null;
SQLDataLayer dl = this.dl ?? (dlDispose = new SQLDataLayer(connString));
using (dlDispose) { dl.Blah(...) }
This also fixes the bug where you leave the class field referring to a short-lived connection that you're also disposing.
For more general usefulness, it is helpful to have a holder class that implements Dispose and will conditionally call Dispose on the object it holds.

Related

How do I bind to a list of string I've created?

I have created a list within this class called myVar...
class FailedIgnoredRetrieved
{
public static async Task FailedIgnoredRetrievedAndShow(ListView commentLabel)
{
void AllEventsComment(string comment)
{
if (commentLabel != null)
{
commentLabel.ItemsSource += comment; //+ "\n";
}
}
AllEventsComment("...");
var api = new ApiClient();
var retrieved = ApiToken.Load();
if (retrieved == null)
{
AllEventsComment("Failed, not signed in");
App.SwitchIcon(NotifyIcons.GreyIcon);
}
else
{
var result = await api.GetAllEventsAsync(retrieved.Token);
if (result.IsSuccessful)
{
List<string> myVar = new List<string>();
void AddToList(string v)
{
myVar.Add(v);
}
foreach (var eventsText in result.Events)
if (eventsText.EventStatus == 1)
{
AddToList($"Red {eventsText.CheckId}");
}
else if (eventsText.EventStatus == 0)
{
AddToList($"Orange {eventsText.CheckId}");
}
}
}
}
}
}
I now want to use myVar List in FailedIgnoredWindow.xaml.cs to bind to for a ListView in FailedIgnoredWindow.xaml I'm struggling to understand how to set it as the ListView.ItemSource = i.e. how do I access the list in the other class?
public partial class FailedIgnoredWindow : Window
{
public FailedIgnoredWindow()
{
InitializeComponent();
FailedIgnoredDialogue.ItemsSource =
}
private async void AllEvents_Click(object sender, RoutedEventArgs e)
{
AllEventsWindow win2 = new AllEventsWindow();
this.Visibility = Visibility.Hidden;
win2.WindowStartupLocation = 0;
//win2.Left = 0;
//win2.Top = 0;
win2.Show();
await AllEventsRetrieved.AllEventsRetrievedAndShowCount(win2.AllEventsDialogue);
}
}
I've tried to create a seperate class with the properties but I'm struggling to fully understand what I need to do.
myVar is declared inside the méthod so it will only be accessible inside this method.
If you want to access it from outside, you should make it a public property of the class FailedIgnoredRetrieved (note that in this case if you want to modify the property from the method FailedIgnoredRetrievedAndShow you will have to make it not static)
Another way would be to have the method return the list so you get it as result (the declaration would become Task<List<string>>FailedIgnoredRetrievedAndShow(... ).
There seems to be quite a bit of confusion in your code so I would recommend reading a tutorial about the scope of variable you can start here
You should also check this answer about the access modifiers here
I would also recommend staying away from local functions (functions inside functions) at the beginning as I think it adds to the confusion.
Let me know if it makes more sense after reading the links in my answer

Deserialize object to itself

I have found some threads about this problem, like this and this but I cannot figure out how I could implement this for my code.
I have something like this:
public sealed class Party
{
public Party()
{
load();
}
....
public async void Load()
{
string fileName = this.Name + ".xml";
var files = ApplicationData.Current.LocalFolder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName).GetResults();
var file = files.FirstOrDefault(f => f.Name == fileName);
if (file != null)
{
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(fileName))
{
XmlSerializer serializer = new XmlSerializer(typeof(Party));
Party data = (Party)serializer.Deserialize(stream);
this = data;
}
}
}
}
This throws me the "cannot assign to ' this ' because it is read-only". Since I read a file and I need to await it, it have to be async, and then I cannot have the class as a return type.
Any ideas for how to deserialize this to itself?
You can't assign to this. It's an instance of an object, and it makes no sense to change it.
Either have a static method that returns the Party (and use that to create the class):
public static Party Load()
{
// ... Deserialize
return (Party)serializer.Deserialize(stream);
}
Or load the information into your class using the deserialized object (which would be inefficient, since they're the same type):
public void Load()
{
// ... Deserialize
Party data = (Party)serializer.Deserialize(stream);
this.Name = data.Name;
this.PartyInfo = data.PartyInfo;
}
Clearly, the static method should be preferred here, and is considered the factory pattern.

A way to call method once

I have the following, I want to move the setting of webDB and item outside of the following public string method which is an example how would I go about doing this.
public string Width
{
get
{
if (webDB != null)
{
webDB = Sitecore.Configuration.Factory.GetDatabase("web");
Sitecore.Data.Items.Item item = webDB.Items[StartItem];
if (item != null)
{
Sitecore.Data.Fields.Field field = item.Parent.Fields["Identity_Page_Width"];
if (!String.IsNullOrEmpty(field.Value))
{
return field.Value;
}
else
{
return "964"; // returns default pixel width if Identity_Page_Width is not defined, or is null
}
}
else
{
return "964"; // If item is not found return default width.
}
}
else
{
return "964";
}
}
}
This is how I have attempted to separate it:
public void GetConfiguration()
{
if (webDB != null)
{
webDB = Sitecore.Configuration.Factory.GetDatabase("web");
if (item != null)
{
item = webDB.Items[StartItem];
}
}
}
but I get stuck with trying to run the method within the code I get method must have a return type.
I then want to run this GetConfiguration only ONCE within the class somewhere so all methods don't need to contact the database and items data more then they have to.
I could do MyClass class = New MyClass; Class.GetConfiguration(); but I don't want future coders to have to know this needs to be instantiated every time to continue. I would rather remove that dependency.
If webDB being instantiated is critical for most/all functionality of the class, consider initializing it in the instance constructor (if non-static), or a static constructor (if static)
Otherwise, I would create a
private InitializeWebDB(){if(webDB == null){...}}
which you can call within your class when needed.
Further, on properties which require access to this, I would use methods instead such as:
public String GetWidth(){InitializeDB(); ...}
which implies more logic/overhead than a simple property field return.
Your code can be improved in a few ways. But to answer your question -
Why not use a static c'tor? This way you ensure it only runs once
public class SomeClass
{
static SomeClass()
{
if (webDB != null)
// etc. etc.
}
... // other code
}
Making the webDB variable static would impose that it will only be null in your first Property call.
private static <whatevertype> webDB;
private static <whatevertype> item;
public void GetConfiguration()
{
if (webDB == null)
{
webDB = Sitecore.Configuration.Factory.GetDatabase("web");
if (item != null)
item = webDB.Items[StartItem];
}
}

Determining if a method calls a method in another assembly containing a new statement and vice-versa

I want to write a rule that will fail if an object allocation is made within any method called by a method marked with a particular attribute.
I've got this working so far, by iterating up all methods calling my method to check using CallGraph.CallersFor(), to see if any of those parent methods have the attribute.
This works for checking parent methods within the same assembly as the method to be checked, however reading online, it appears that at one time CallGraph.CallersFor() did look at all assemblies, however now it does not.
Question: Is there a way of getting a list of methods that call a given method, including those in a different assembly?
Alternative Answer: If the above is not possible, how do i loop through every method that is called by a given method, including those in a different assembly.
Example:
-----In Assembly A
public class ClassA
{
public MethodA()
{
MethodB();
}
public MethodB()
{
object o = new object(); // Allocation i want to break the rule
// Currently my rule walks up the call tree,
// checking for a calling method with the NoAllocationsAllowed attribute.
// Problem is, because of the different assemblies,
// it can't go from ClassA.MethodA to ClassB.MethodB.
}
}
----In Assembly B
public var ClassAInstance = new ClassA();
public class ClassB
{
[NoAllocationsAllowed] // Attribute that kicks off the rule-checking.
public MethodA()
{
MethodB();
}
public MethodB()
{
ClassAInstance.MethodA();
}
}
I don't really mind where the rule reports the error, at this stage getting the error is enough.
I got round this issue by adding all referenced dlls in my FxCop project, and using the code below, which builds a call tree manually (it also adds calls for derived classes to work round another problem i encountered, here.
public class CallGraphBuilder : BinaryReadOnlyVisitor
{
public Dictionary<TypeNode, List<TypeNode>> ChildTypes;
public Dictionary<Method, List<Method>> CallersOfMethod;
private Method _CurrentMethod;
public CallGraphBuilder()
: base()
{
CallersOfMethod = new Dictionary<Method, List<Method>>();
ChildTypes = new Dictionary<TypeNode, List<TypeNode>>();
}
public override void VisitMethod(Method method)
{
_CurrentMethod = method;
base.VisitMethod(method);
}
public void CreateTypesTree(AssemblyNode Assy)
{
foreach (var Type in Assy.Types)
{
if (Type.FullName != "System.Object")
{
TypeNode BaseType = Type.BaseType;
if (BaseType != null && BaseType.FullName != "System.Object")
{
if (!ChildTypes.ContainsKey(BaseType))
ChildTypes.Add(BaseType, new List<TypeNode>());
if (!ChildTypes[BaseType].Contains(Type))
ChildTypes[BaseType].Add(Type);
}
}
}
}
public override void VisitMethodCall(MethodCall call)
{
Method CalledMethod = (call.Callee as MemberBinding).BoundMember as Method;
AddCallerOfMethod(CalledMethod, _CurrentMethod);
Queue<Method> MethodsToCheck = new Queue<Method>();
MethodsToCheck.Enqueue(CalledMethod);
while (MethodsToCheck.Count != 0)
{
Method CurrentMethod = MethodsToCheck.Dequeue();
if (ChildTypes.ContainsKey(CurrentMethod.DeclaringType))
{
foreach (var DerivedType in ChildTypes[CurrentMethod.DeclaringType])
{
var DerivedCalledMethod = DerivedType.Members.OfType<Method>().Where(M => MethodHidesMethod(M, CurrentMethod)).SingleOrDefault();
if (DerivedCalledMethod != null)
{
AddCallerOfMethod(DerivedCalledMethod, CurrentMethod);
MethodsToCheck.Enqueue(DerivedCalledMethod);
}
}
}
}
base.VisitMethodCall(call);
}
private void AddCallerOfMethod(Method CalledMethod, Method CallingMethod)
{
if (!CallersOfMethod.ContainsKey(CalledMethod))
CallersOfMethod.Add(CalledMethod, new List<Method>());
if (!CallersOfMethod[CalledMethod].Contains(CallingMethod))
CallersOfMethod[CalledMethod].Add(CallingMethod);
}
private bool MethodHidesMethod(Method ChildMethod, Method BaseMethod)
{
while (ChildMethod != null)
{
if (ChildMethod == BaseMethod)
return true;
ChildMethod = ChildMethod.OverriddenMethod ?? ChildMethod.HiddenMethod;
}
return false;
}
}
Did you give it a try in this way,
StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
object [] items = methodBase.GetCustomAttributes(typeof (NoAllocationsAllowed));
if(items.Length > 0)
//do whatever you want!

Which design patterns to use to implement this business logic?

I am trying to determine the best design pattern to use for a business key validation web service. The basic logic flow is coded below. The program will take a parameter and use a field to help determine the path to take in searching multiple systems where this business key can be found. System1 is searched first, if not found, search System2 and System3. The System1 search logic depends on a field in the parameter passed into the original validation method.
I am not exactly sure which design pattern to use. It looks like Command, Chain of Responsibility, Template Method all could be used here.
With my implementations below, I see the following problems:
Each SearchSystemX method needs to know to return null if the business key is not found so that the "control" method will continue to search other systems.
Each SearchSystemX must know how to populate the business object, currently just implemented by a simple primitive string, but that is for example only.
Please let me know your thoughts.
public string Validate (string parms) {
string returnValue = null;
returnValue = SearchSystem1(parms);
if (returnValue == null) {
returnValue = SearchSystem2(parms);
if (returnValue != null) {
returnValue = SearchSystem3(parms);
}
else if (returnValue == null) {
if (parms == "Criteria1") {
returnValue = SearchSystem4(parms);
if (returnValue == null) {
throw new ApplicationException("ID Invalid");
}
}
else if (parms == "Criteria2") {
throw new ApplicationException("ID Invalid");
}
}
}
return returnValue;
private string SearchSystem1 (string parms) {
string returnValue = null;
if (parms == "Criteria1") {
returnValue = SearchSystem1UsingColumn1(parms);
}
else if (parms == "Criteria2") {
returnValue = SearchSystem1UsingColumn2(parms);
if (returnValue == null) {
returnValue = SearchSystem1UsingColumn4(parms);
}
}
if (returnValue != null) {
returnValue = FetchXYCoordinate(parms);
}
return returnValue;
}
Thanks!
Chain of responsability
Each processing object contains a set of logic that describes the types of command objects that it can handle, and how to pass off those that it cannot to the next processing object in the chain
So you define and abstract SearchSystem ( or SystemSearch ) and add subclasses like this:
class SearchSystem
{
//link to the next in the chain
SearchSystem next;
// Basic search, If cannot handle forward to the next.
public Result search( Criteria c )
{
Result r = doSearch( c );
if( r != null )
{
return r;
}
return next.search( c );
}
// subclass specific system search
abstract Result doSearch( Criteria c );
}
class SearchSystemOne: SearchSystem
{
Result doSearch( Criteria c )
{
// do some system 1 speficif stuff
// and return either and instance or null
}
}
class SearchSystemTwo: SearchSystem
{
Result doSearch( Criteria c )
{
// do some system 2 speficif stuff
// and return either and instance or null
}
}
.... etc etc.
// End of the chain
class SearchSystemOver: SearchSystem
{
public Result search( Criteria c )
{
throw new ApplicationException("Criteria not foud", c );
}
Result doSearch( Criteria c )
{
// didn't we throw exception already?
}
}
Instantiate
SearchSystem one = new SearchSystemOne();
SearchSystem two = new SearchSystemTwo();
SearchSystem three = new SearchSystemThree();
SearchSystem four = new SearchSystemFour();
SearchSystem over = new SearchSystemOver();
And build the chain
one.next = two;
two.next = three;
three.next = four;
four.next = over;
And finally search it.
SearchSystem searcher = one;
searcher.search( Criteria.addName("Oscar").addLastName("Reyes"));
Possibly the Strategy Pattern.
It allows you to abstract away the algorithms you're using to perform the logic, encapsulate them in their own objects, and then use them interchangeably throughout your application (allow the caller to define which algorithm to use).
I'd probably use the strategy pattern here by defining an interface for the search system(s):
public interface ISearchStrategy
{
string Search(string criteria);
}
and then passing them to the validate method (although the validation class could get them from somewhere else).
public string Validate(string parms, IEnumerable<ISearchStrategy> searchStrategies)
{
string returnValue = null;
foreach(var strategy in searchStrategies)
{
if(returnValue == null)
{
returnValue = strategy.Search(parms);
}
}
if(returnValue == null) throw new ApplicationException("ID invalid");
return returnValue;
}
Without knowing more about your domain, I can only suggest minor tweaks. First would be to use guard clauses.
Also you mention how the SearchSystems need to know how to build a business object. I would make sure the SearchSystems can be treated polymorphically (that way you have a path to refactoring out a strategy or some kind of dependency injection). Also I would favor a SystemSearcher over a family of SearchSystem methods. Then I would inject into the SearchSystems a business object factory. I would also design the behavior with TryXXX semantics.
public interface ISearchSystem
{
bool TryGet(string parms, out string businessObject);
}
public class System1Searcher : ISearchSystem
{
public System1Searcher(BusinessObjectFactory factory) { _factory = factory; }
private field BusinessObjectFactory _factory;
public bool TryGet(string parms, out string businessObject)
{
// do internal logic
return _factory.Create(string stuff);
}
}
public class Service
{
// is "Validate" the correct metaphor for this logic?
public string Validate(string parms)
{
string returnValue = null;
if (new System1Searcher().TryGet(parms, out returnValue)
return returnValue;
if (new System2Searcher().TryGet(parms, out returnValue)
return returnValue;
if (new System3Searcher().TryGet(parms, out returnValue)
return returnValue;
if (new System4Searcher().TryGet(parms, out returnValue)
return returnValue;
// this message should be written in terms of the logic of this method
// such as "Parameters invalid"
throw new ApplicationException("ID Invalid");
}
}

Categories

Resources