This is an extremely simplified example of something I'm already doing in Grails:
// this can be a service or normal class
public abstract class Person {
public final String introduceSelf() {
return "Hi, I'm " + getFullName()
}
protected abstract String getFullName()
}
// Service
class AlexService extends Person {
protected String getFullName() {
return "Alex Goodman"
}
}
// Service
class BobService extends Person {
protected String getFullName() {
return "Bob Goodman"
}
}
// Service
class CarlService extends Person {
protected String getFullName() {
return "Carl Goodman"
}
}
// Controller
class IntroduceController {
def alex
def bob
def carl
def index() {
if(params.person == "a")
render alex.introduceSelf()
if(params.person == "b")
render bob.introduceSelf()
if(params.person == "c")
render carl.introduceSelf()
}
}
I'm looking for more object oriented way of doing it, something like:
// Controller
class IntroduceController {
def person
def index() {
// inject a proper person in a more object oriented way
render person.introduceSelf()
}
}
Can you suggest how to achieve this in a more object-oriented/dynamic way?
You can write a person bean definition in grails-app/conf/spring/resources.groovy file. For example:
beans = {
person(BobService)
}
For more information, check this: http://grails.org/doc/latest/guide/spring.html#springdslAdditional
class IntroduceController {
def grailsApplication
def index() {
def person = grailsApplication.mainContext.getBean( params.person )
person.doSomething()
}
}
You must make sure, that your services' names correspond to params.person value, params.person = 'bob' would work, params.person = 'b' would not
Related
I have a method ResetMethod(ClassA a) in a class and I have accessed this method by property of ResetMethod's class like this:
public class MyClass1
{
public MyClass1()
{
}
public void ResetMethod(ClassA a)
{
}
}
public class MyClass2
{
MyClass1 class1;
public MyClass2()
{
ClassA a= new ClassA();
MyClass1.ResetMethod(a);
}
public MyClass1 MyClass1
{
get
{
if (myClass1 == null)
myClass1 = new MyClass1 ();
return myClass1 ;
}
set
{
myClass1 = value;
}
}
}
While running FxCop rules, for method ResetMethod, it shows this error:
The 'this' parameter (or 'Me' in Visual Basic) of 'MyClass1.ResetMethod(MyClassA)' is never used. Mark the member as static (or Shared in Visual Basic) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate.
How do I resolve this error?
You invocation of MyClass1.ResetMethod(a); is already calling a static method. So the code you posted does not compile to my understanding.
So all that's left to the do is to make the method itself static:
public static void ResetMethod(ClassA a)
{
// ...
}
Get data from a derived class..
My samples.
public class Maintest
{
public string name = "2";
}
public class test : Maintest
{
string bla = name;
}
or
public class test : Maintest
{
test child = new test();
string bla = child.name;
}
Please reply
or
Share a link to explore
For example there is the main class
and I have a derived class that will output data of the first class.
As an example, I just wanted to pass the value of the derivative in the main class. For a proper understanding
If you return the field from a property, it might look a little something like this.
using System;
public class Program
{
public void Main()
{
var test = new Test();
Console.WriteLine(test.greeting);
}
}
// make this abstract if you're never directly instantiate MainTest
public abstract class MainTest
{
public string name = "world";
}
public class Test : MainTest
{
public string greeting {get { return "Hello " + name;}}
}
http://dotnetfiddle.net/R8kwh3
Also, you can enforce a contract by doing something like
public abstract class MainTest
{
public string name = "world";
// create an abstract property to ensure it gets implemented in the inheriting class
public abstract string greeting {get; private set;}
}
public class Test : MainTest
{
public override string greeting {get { return "Hello " + name;}}
}
Maybe you want get data in method? Therefore, you can use this:
public class test : Maintest
{
public string GetData()
{
return name;
}
}
public interface IFoo {}
public class Foo : IFoo {}
public sealed class NinjaModule : NinjectModule //Appropriately configured in project
{
public override void Load()
{
Bind<IFoo>.To<Foo>.InTransientScope();
}
}
public class SomeOtherClass : ISomeOtherInterface
{
public SomeOtherClass();
public IFoo GetFoo(IFoo foo)
{
return foo;
}
public void GetFoos()
{
foreach (var thing in everything)
{
var localFoo = GetFoo();
localFoo.UniqueProperty = "I am unique";
_fooList.Add(localFoo);
}
}
}
I need my code to look something like that.
Yes, I am fairly new to inject. I am fairly certain that I am missing a basic principle.
Thanks for any help.
I think the best approach here would be to use a factory to create the different Foo instances. And with Ninject and the Factory extension that's pretty easy.
public sealed class NinjaModule : NinjectModule //Appropriately configured in project
{
public override void Load()
{
Bind<IFoo>().To<Foo>().InTransientScope();
Bind<IFooFactory>().ToFactory();
}
}
public interface IFooFactory
{
IFoo CreateFoo();
}
public class SomeOtherClass : ISomeOtherInterface
{
private IFooFactory fooFactory;
public SomeOtherClass(IFooFactory fooFactory)
{
this.fooFactory = fooFactory;
}
public IFoo GetFoo(IFoo foo)
{
return this.fooFactory.CreateFoo();
}
public void GetFoos()
{
foreach (var thing in everything)
{
var localFoo = GetFoo();
localFoo.UniqueProperty = "I am unique";
_fooList.Add(localFoo);
}
}
}
This was a bad question. I figured out this needed to be implemented higher up by the class controlling these implementations.
I have a Singleton class that uses the thread-safe Singleton pattern from Jon Skeet as seen in the TekPub video. The class represents a cached list of reference data for dropdowns in an MVC 3 UI.
To get the list data the class calls a static method on a static class in my DAL.
Now I'm moving into testing an I want to implement an interface on my DAL class but obviously cannot because it is static and has only one static method so there's no interface to create. So I want to remove the static implementation so I can do the interface.
By doing so I can't call the method statically from the reference class and because the reference class is a singleton with a private ctor I can't inject the interface. How do I get around this? How do I get my interface into the reference class so that I can have DI and I can successfully test it with a mock?
Here is my DAL class in current form
public static class ListItemRepository {
public static List<ReferenceDTO> All() {
List<ReferenceDTO> fullList;
... /// populate list
return fullList;
}
}
This is what I want it to look like
public interface IListItemRepository {
List<ReferenceDTO> All();
}
public class ListItemRepository : IListItemRepository {
public List<ReferenceDTO> All() {
List<ReferenceDTO> fullList;
... /// populate list
return fullList;
}
}
And here is my singleton reference class, the call to the static method is in the CheckRefresh call
public sealed class ListItemReference {
private static readonly Lazy<ListItemReference> instance =
new Lazy<ListItemReference>(() => new ListItemReference(), true);
private const int RefreshInterval = 60;
private List<ReferenceDTO> cache;
private DateTime nextRefreshDate = DateTime.MinValue;
public static ListItemReference Instance {
get { return instance.Value; }
}
public List<SelectListDTO> SelectList {
get {
var lst = GetSelectList();
lst = ReferenceHelper.AddDefaultItemToList(lst);
return lst;
}
}
private ListItemReference() { }
public ReferenceDTO GetByID(int id) {
CheckRefresh();
return cache.Find(item => item.ID == id);
}
public void InvalidateCache() {
nextRefreshDate = DateTime.MinValue;
}
private List<SelectListDTO> GetSelectList() {
CheckRefresh();
var lst = new List<SelectListDTO>(cache.Count + 1);
cache.ForEach(item => lst.Add(new SelectListDTO { ID = item.ID, Name = item.Name }));
return lst;
}
private void CheckRefresh() {
if (DateTime.Now <= nextRefreshDate) return;
cache = ListItemRepository.All(); // Here is the call to the static class method
nextRefreshDate = DateTime.Now.AddSeconds(RefreshInterval);
}
}
}
You can use the singleton based on instance(not based on static), for which you can declare interface like this.
public interface IListItemRepository
{
List<ReferenceDTO> All();
}
public class ListItemRepository : IListItemRepository
{
static IListItemRepository _current = new ListItemRepository();
public static IListItemRepository Current
{
get { return _current; }
}
public static void SetCurrent(IListItemRepository listItemRepository)
{
_current = listItemRepository;
}
public List<ReferenceDTO> All()
{
.....
}
}
Now, you can mock IListItemRepository to test.
public void Test()
{
//arrange
//If Moq framework is used,
var expected = new List<ReferneceDTO>{new ReferneceDTO()};
var mock = new Mock<IListItemRepository>();
mock.Setup(x=>x.All()).Returns(expected);
ListItemRepository.SetCurrent(mock.Object);
//act
var result = ListItemRepository.Current.All();
//Assert
Assert.IsSame(expected, result);
}
Which DI framework are you using? Depending on your answer, IOC container should be able to handle single-instancing so that you don't have to implement your own singleton pattern in the caching class. In your code you would treat everything as instanced classes, but in your DI framework mappings you would be able to specify that only one instance of the cache class should ever be created.
One way to test it would be if you refactor your ListItemReference by adding extra property:
public sealed class ListItemReference {
...
public Func<List<ReferenceDTO>> References = () => ListItemRepository.All();
...
private void CheckRefresh() {
if (DateTime.Now <= nextRefreshDate) return;
cache = References();
nextRefreshDate = DateTime.Now.AddSeconds(RefreshInterval);
}
}
And then in your test you could do:
ListItemReference listReferences = new ListItemReference();
listReferences.References = () => new List<ReferenceDTO>(); //here you can return any mock data
Of course it's just temporary solution and I would recommend getting rid of statics by using IoC/DI.
So I have these to classes, one is my superclass the other is my subclass. I am having trouble calling my sub class method in my superclass method so I can get these results also. the methods are overloading and I am having a problem understanding it. I think If I can get this, it will help me understand how the two interlink and work.
I am having trouble in my copy constructor, toString method and equals method in my subclass
Superclass:
public class Car
{
private String make;
private String model;
private int miles;
// The default constructor—use this
public Car()
{
this.make=null;
this.model=null;
this.miles=0;
}
// The 3-parameter constructor –use this
public Car(String make,String model,int miles)
{
this.make=make;
this.model=model;
this.miles=miles;
}
// The copy constructor—use this
public Car(Car obj)
{
this.make=obj.make;
this.model=obj.model;
this.miles=obj.miles;
}
// The toString method—use this
public String toString()
{
String str;
str = "The car Brand: "+ this.make +" Mobel: "+this.model+" miles on the car: "+this.miles;
return str;
}
// The equals method—use this
public boolean equals(Car obj)
{
if (this.make.equals(obj.make)&&this.model.equals(obj.model)&&this.miles==obj.miles)
return true;
else
return false;
}
}
//My subclass method
public class Convertible extends Car
{
private String typeTop;
// The default constructor—use this
public Convertible()
{
super();
this.typeTop= null;
}
// The 4-parameter constructor—use this
public Convertible(String make, String model,int miles,String typeTop)
{
super(make,model,miles);
this.typeTop=typeTop;
}
// The copy constructor—use this
public Convertible(Convertible obj)
{
super(Convertible obj);
this.typeTop=obj.typeTop;
}
// The toString method—use this
public String toString()
{
String str;
str =super.toString()+this.typeTop;
return str;
}
// The equals method—use this
public boolean equals(Convertible obj)
{
if(super.equals(super.obj)&&this.typeTop.equals(obj.typeTop))
return true;
else
return false;
}
}
change line number 29 in Convertible class to super(obj);
and 43 to if (super.equals(obj) && this.typeTop.equals(obj.typeTop)) {