How to define a helper method shared by multiple classes? - helper

what would be the best way to go about this? For instance, consider the following code:
public class ObjectA {
public int data;
public ObjectA() {
this.data = 1;
}
public changeData(int x) {
this.data = x;
}
}
public class ObjectB {
public int data;
public ObjectB() {
this.data = 1;
}
public changeData(int x) {
this.data = x;
}
}
How can this be refactored so changeData can have both classes can use it? Also, so that changeData will be safe to use.

You could create your helper function and data as part of a base class and derive all other classes from it.

Related

Fluent NHibernate reference / many-to-one mapping cascade all not working

I have some problem with cascade all (orphan) and delete the old objcet from the database.
Example:
I have an class A which contains an object of class B. Now, when I create an object of class A and save it, everything works fine. When I call the method SetValueOfB(int i) and save the object A again, the old object B is still in the database.
Must the association between the classes always be directional (for every HasMany/Reference/HasOne...)? (But object b has nothing to know about object a)
Is there a way to solve the problem with unidirectional association?
Do I need a one-to-one mapping? Because the object B can only belong to object A (A is a parameter and B is a value).
Here is a failing test:
using System.Collections.Generic;
using System.Data;
using System.IO;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Mapping;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;
namespace ReferenceCascade.Test
{
public class CascadeTest
{
private const string DbFile = "firstProject.db";
[Test]
public void checkCascadeAll()
{
var sessionFactory = CreateSessionFactory();
A testee = new A(new B(1));
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.SaveOrUpdate(testee);
transaction.Commit();
}
}
testee.SetValueOfB(2);
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.SaveOrUpdate(testee);
transaction.Commit();
}
}
using (var session = sessionFactory.OpenSession())
{
using (session.BeginTransaction())
{
IList<B> stores = session.CreateCriteria(typeof(B))
.List<B>();
Assert.That(stores.Count, Is.EqualTo(1));
}
}
}
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile(DbFile).IsolationLevel(IsolationLevel.ReadCommitted))
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<CascadeTest>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private static void BuildSchema(Configuration config)
{
// delete the existing db on each run
if (File.Exists(DbFile))
{
File.Delete(DbFile);
}
// this NHibernate tool takes a configuration (with mapping info in)
// and exports a database schema from it
new SchemaExport(config)
.Create(false, true);
}
}
public abstract class Entity
{
public const long InitialId = 0;
private readonly long _id;
protected Entity()
{
_id = InitialId;
}
public virtual long Id
{
get { return _id; }
}
}
public class A : Entity
{
private B _b;
public A()
{
}
public A(B b)
{
_b = b;
}
public virtual void SetValueOfB(int i)
{
_b = new B(i);
}
public virtual B B
{
get { return _b; }
}
}
public class B : Entity
{
private readonly int _i;
public B()
{
}
public B(int i)
{
_i = i;
}
public virtual int I
{
get { return _i; }
}
}
public class EntityMap<T> : ClassMap<T> where T : Entity
{
public EntityMap()
{
Id(x => x.Id).GeneratedBy.HiLo("33878").Access.CamelCaseField(Prefix.Underscore);
}
}
public class AMap : EntityMap<A>
{
public AMap()
{
Table("A");
References(x => x.B).Not.LazyLoad().Cascade.All().Access.CamelCaseField(Prefix.Underscore);
}
}
public class BMap : EntityMap<B>
{
public BMap()
{
Table("B");
Map(x => x.I).Not.LazyLoad().Access.CamelCaseField(Prefix.Underscore);
}
}
}
Or here is the project: vs project
We haven't found a way to solve the problem. In NHibernate version 4.1, the problem will be fixed and it is possible to use cascade=all-delete-orphan with many-to-one. See here: https://nhibernate.jira.com/browse/NH-1262

Is there a way to find out which class instance created 'this'

**I(one instance of a class) want to find out say which class instantiated me?
I have a class C that is instantiated by Class A and Class B. I want to find out which class instantiated me, so that I can access the variable from that class.
The usual way is to pass in an identifier that hey I am from class A and pass in the variable x in the constructor for the C to consume in the way appropriate for it.
**
eg:
public Class A
{
public int x;
public A()
{
C c = new C();
}
}
public Class B
{
public int x;
public B()
{
C c = new C();
}
}
public Class C
{
public CMethod()
{
// I want Access int x from the class that instantiated me.
if I know its B then B.x ...
}
}
There is no way to know without some hacking (see below). This looks like a case for an interface…
Classes A and B define HasX which has a getX() method. You can pass either class to the constructor of C which expects any class which implements HasX. Then C can call getX on either object and it doesn't need to know which type it actually is, but it will get the appropriate X value.
public interface HasX {
public int getX();
}
public class A implements HasX {
private int x;
public A()
{
C c = new C(this);
}
public int getX() {
return x;
}
}
public class B implements HasX {
private int x;
public B() {
C c = new C(this);
}
public int getX() {
return x;
}
}
public class C {
HasX hasX;
public C(HasX hasX) {
this.hasX = hasX;
}
public void doStuff() {
int x = hasX.getX();
}
}
To answer you original question though, the object which created an object is not stored anywhere… but you can do some hacking when C is constructed for find out the class. Here is some code I once used for a Logging implementation which could detect who was the caller by looking back along the stracktrace of a Throwable. Again, this is not good practice, but you asked so… :)
From: https://github.com/slipperyseal/atomicobjects/blob/master/atomicobjects-lang/src/main/java/net/catchpole/trace/PrintTrace.java
public C() {
String whoCalledMe = whereAmI(new Throwable());
}
private String whereAmI(Throwable throwable) {
for (StackTraceElement ste : throwable.getStackTrace()) {
String className = ste.getClassName();
// search stack for first element not within this class
if (!className.equals(this.getClass().getName())) {
int dot = className.lastIndexOf('.');
if (dot != -1) {
className = className.substring(dot + 1);
}
return className + '.' + ste.getMethodName();
}
}
return "";
}
You might want to edit this to simply return the class name, or even do a Class.forName() to resolve the actual class.
If you want the actual objects, and there is only ever 1 of each class, you could out the objects in a Map keyed on classname. But gee what a mess around :)

How is IClock resolved with SystemClock in this example?

I am trying to learn IOC principle from this screencast
Inversion of Control from First Principles - Top Gear Style
I tried do as per screencast but i get an error while AutomaticFactory try create an object of AutoCue. AutoCue class has contructor which takes IClock and not SystemClock. But my question is , in screencast IClock is resolved with SystemClock while inside AutomaticFactory .But in my code , IClock does not get resolved . Am i missing something ?
class Program
{
static void Main(string[] args)
{
//var clarkson = new Clarkson(new AutoCue(new SystemClock()), new Megaphone());
//var clarkson = ClarksonFactory.SpawnOne();
var clarkson = (Clarkson)AutomaticFactory.GetOne(typeof(Clarkson));
clarkson.SaySomething();
Console.Read();
}
}
public class AutomaticFactory
{
public static object GetOne(Type type)
{
var constructor = type.GetConstructors().Single();
var parameters = constructor.GetParameters();
if (!parameters.Any()) return Activator.CreateInstance(type);
var args = new List<object>();
foreach(var parameter in parameters)
{
var arg = GetOne(parameter.ParameterType);
args.Add(arg);
}
var result = Activator.CreateInstance(type, args.ToArray());
return result;
}
}
public class Clarkson
{
private readonly AutoCue _autocue;
private readonly Megaphone _megaphone;
public Clarkson(AutoCue autocue,Megaphone megaphone)
{
_autocue = autocue;
_megaphone =megaphone;
}
public void SaySomething()
{
var message = _autocue.GetCue();
_megaphone.Shout(message);
}
}
public class Megaphone
{
public void Shout(string message)
{
Console.WriteLine(message);
}
}
public interface IClock
{
DateTime Now { get; }
}
public class SystemClock : IClock
{
public DateTime Now { get { return DateTime.Now; } }
}
public class AutoCue
{
private readonly IClock _clock;
public AutoCue(IClock clock)
{
_clock = clock;
}
public string GetCue()
{
DateTime now = _clock.Now;
if (now.DayOfWeek == DayOfWeek.Sunday)
{
return "Its a sunday!";
}
else
{
return "I have to work!";
}
}
}
What you basically implemented is a small IoC container that is able to auto-wire object graphs. But your implementation is only able to create object graphs of concrete objects. This makes your code violate the Dependency Inversion Principle.
What's missing from the implementation is some sort of Register method that tells your AutomaticFactory that when confronted with an abstraction, it should resolve the registered implementation. That could look as follows:
private static readonly Dictionary<Type, Type> registrations =
new Dictionary<Type, Type>();
public static void Register<TService, TImplementation>()
where TImplementation : class, TService
where TService : class
{
registrations.Add(typeof(TService), typeof(TImplementation));
}
No you will have to do an adjustment to the GetOne method as well. You can add the following code at the start of the GetOne method:
if (registrations.ContainsKey(type))
{
type = registrations[type];
}
That will ensure that if the supplied type is registered in the AutomaticFactory as TService, the mapped TImplementation will be used and the factory will continue using this implementation as the type to build up.
This does mean however that you now have to explicitly register the mapping between IClock and SystemClock (which is a quite natural thing to do if you're working with an IoC container). You must make this mapping before the first instance is resolved from the AutomaticFactory. So you should add the following line to to the beginning of the Main method:
AutomaticFactory.Register<IClock, SystemClock>();

How to inherit partial class for stored procedure call

I have this class as parent class:
public partial class GetStuffResult
{
private int _Id;
private string _Name;
public GetStuffResult()
{
}
[Column(Storage="_Id", DbType="INT NOT NULL")]
public int Id
{
get
{
return this._Id;
}
set
{
if ((this._Id != value))
{
this._Id = value;
}
}
}
[Column(Storage="_Name", DbType="NVarChar(100)")]
public string Name
{
get
{
return this._Name;
}
set
{
if ((this._Name != value))
{
this._Name = value;
}
}
}
}
This is base class which has same methods with exception of an extra method:
public partial class GetStuffResult1
{
private int _Score;
private int _Id;
private string _Name;
public GetStuffResult1()
{
}
[Column(Storage="_Score", DbType="INT NOT NULL")]
public int Id
{
get
{
return this._Score;
}
set
{
if ((this._Score != value))
{
this._Score = value;
}
}
}
[Column(Storage="_Id", DbType="INT NOT NULL")]
public int Id
{
get
{
return this._Id;
}
set
{
if ((this._Id != value))
{
this._Id = value;
}
}
}
[Column(Storage="_Name", DbType="NVarChar(100)")]
public string Name
{
get
{
return this._Name;
}
set
{
if ((this._Name != value))
{
this._Name = value;
}
}
}
}
I have done inheritance before but i am totally confused how it will work in this scenario? How can i inherit GetStuffResult so that i can use its 2 methods and dont have to copy paste same code twice in GetStuffResult1.
Will appreciate if someone can give example with code as i am new to .net 3.5 and still trying to learn it.
I am not sure if I correctly understood your question. (Your current code for GetStuffResult1 shouldn't compile as you have define Id property twice.) If you are looking to inherit from GetStuffResult then this would do (See Inheritance):
public partial class GetStuffResult1 : GetStuffResult
{
private int _Score;
public GetStuffResult1()
{
}
[Column(Storage = "_Score", DbType = "INT NOT NULL")]
public int Id
{
get
{
return this._Score;
}
set
{
if ((this._Score != value))
{
this._Score = value;
}
}
}
}
Notice that I have removed _Id and _Name from the child class. This however will give you warning that:
GetStuffResult1.Id' hides inherited member
'ThreadConsoleApp.GetStuffResult.Id'. Use the new keyword if hiding
was intended.
The second thing I am thinking about your question if you are confused about using partial classes and you may need a single class in multiple source file. In that case you may use partial keyword. If that is the case and you don't need inheritance then you need to use a single name for the class. e.g. GetStuffResult. In that particular case your GetStuffResult1 will become:
public partial class GetStuffResult
{
private int _Score;
public GetStuffResult1()
{
}
[Column(Storage = "_Score", DbType = "INT NOT NULL")]
public int Id
{
get
{
return this._Score;
}
set
{
if ((this._Score != value))
{
this._Score = value;
}
}
}
}
This will be similar to having a single class with all the combined properties.
Edit:
To access the base class properties in the child class, you may use base keyword.
base.Id = 0;
base.Name = "SomeName";
To access the base class properties from the object of GetStuffResult1, see the following example.
GetStuffResult1 gsr1 = new GetStuffResult1();
gsr1.Id = 0;
gsr1.Name = "SomeName";
Here gsr1.Name is from the base class, you may use different name for Id in either base or child class so that it can be more clearer.

Trying to simplify the code

Does anybody suggest me how can I simplify the follow code
private bool isMethodCalled;
private void CallMethod()
{
if (!isMethodCalled)
{
this.CallCertainMethod();
isMethodCalled = true;
}
}
private int field1;
public int Property1
{
get
{
CallMethod();
return this.field1;
}
set { this.field1 = value; }
}
private int field2;
public int Property2
{
get
{
CallMethod();
return this.field2;
}
set { this.field2 = value; }
}
private int field3;
public int Property3
{
get
{
CallMethod();
return this.field3;
}
set { this.field3 = value; }
}
You could use an AOP framework like PostSharp to create an attribute which would call CallMethod and just use automatic properties for Property1, Property2 and Property3. Although it wouldn't save much in the number of lines of code unless there are a lot of other properties.
Something you can simplify is the following:
private void CallMethod()
{
if (!isMethodCalled)
{
this.CallCertainMethod();
isMethodCalled = true;
}
}
to:
private void CallMethod()
{
if (!isMethodCalled) this.CallCertainMethod();
isMethodCalled = true;
}
As a side note:
I don't know what CallCertainMethod() does. Just in case, it is not recommended to query data and mutate state at the same time. See Command Query-Separation, which states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer.

Resources