I'm playing around with Domain Driven Development. I'm using a generic repository implementation that is defined as follows: (this is implemented as Repository<T>)
public interface IRepository<T> where T : class, IEventSource, new()
{
T FindByKey(Guid key);
IEnumerable<T> FindByQuery(Predicate<T> filter);
IEnumerable<T> GetAll();
T CreateObject();
}
Let's say I have an Order class, that cannot be created without a Customer parameter. I'm using CreateObject to set the Key of the entity with a sequential Guid generator.
What is the solution that minimizes development time and coupling?
Currently I have a parameterless constructor, and am calling some
Initialize(Customer) method.
I could create a ICustomerRepository, but that would mean there is a
lot of extra development time per entity.
I can also modify CreateObject to take params object[] args, but that is not type safe at compile time.
I could remove CreateObject and use constructors to create the object, but that means I need to have access to the the Guid generation algorithm everywhere I instantiate an object, increasing coupling.
In a base class for an entity I could set the key in the constructor, reducing coupling, but requiring some static reference to the algorithm.
Update
I've implemented the strategy following sll's answer. The new signature for the repository is now:
public interface IRepository<T> where T : class, IEventSource
{
T FindByKey(Guid key);
IEnumerable<T> FindByQuery(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T CreateObject();
T CreateObject(IConstructorParameters parameters);
}
The parameterless CreateObject creates an instance by attempting to call the parameterless constructor (using IL Emit for performance).
The second CreateObject attempts to create a method that calls the constructor where the properties on the IConstructorParameters match a constructor on the Entity object.
Implementation:
private Dictionary<Type, Func<IConstructorParameters, T>> _constructionMethods
= new Dictionary<Type, Func<IConstructorParameters, T>>();
public T CreateObject(IConstructorParameters args)
{
T newObject;
if (args == null)
{
args = ConstructorParameters.Empty;
}
Type paramType = args.GetType();
Func<IConstructorParameters, T> constructor;
if (!_constructionMethods.TryGetValue(paramType, out constructor))
{
//Emit IL to create a Func<IConstructorParameters,T>
constructor = CreateConstructor(paramType);
_constructionMethods.Add(paramType, constructor);
}
newObject = constructor(args);
newObject.Key = _guidCreator.Generate();
return newObject;
}
Some points as suggestion, i would do as follows.
Keep IRepository generic, and also create specific interfaces containing the contract only with what is relevant to the entity, ICustomerRepository as your example.
Remove the guid generation to a service class, since this task is most relevant for the infrastructure and not domain.
If you do not want implement IOrderRepository - you can abstract CreateObject() method parameters by an interface like IConstructionParameters and then for each entity implement concrete parameters like OrderConstructionParameters.
This approach also known as Parameter Object design pattern which design rationale - more decoupled system design.
public interface IRepository<T>
{
T CreateObject(IConstructionParameters parameters);
}
public sealed class OrderConstructionParameters : IConstructionParameters
{
public Customer Customer
{
get;
private set;
}
}
Related
In this course project, the teacher created an abstract base class (EfEntityRepositoryBase) for data access, a concrete class for each entity (ProductDal) that inherits abstract base class and implements an interface (IEntityRepository). ProductDal also has its interface (IProductDal) which also implements IEntityRepository.
What is the use case for doing it? I can't understand the point of IProductDal implementing IEntityRepository, since ProductDal already inherits the abstract base class that implements the same interface. So if any function updates in IEntityRepository, should be no problem. If someone can explain so would be great. Below abstract class and interfaces code.
public class ProductDal : EfEntityRepositoryBase<Product>, IProductDal{ }
public interface IEntityRepository<T>
{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
List<T> GetAll(Expression<Func<T, bool>> expression = null);
T GetById(Expression<Func<T, bool>> expression);
}
public interface IProductDal: IEntityRepository<Product>
{
}
public class EfEntityRepositoryBase<TEntity> : IEntityRepository<TEntity> where TEntity : class, IEntity, new()
{
public void Add(TEntity entity)
{
using (BookStoreTrackerDBContext context = new BookStoreTrackerDBContext())
{
var addedEntity = context.Entry(entity);
addedEntity.State = EntityState.Added;
context.SaveChanges();
}
}
}
I think it is easy to understand that you feel, when looking at your provided example, tempted to call out the IProductDal interface as being redundant. In fact, it doesn't add any extra members to the type ProductDal because the interface IProductDal and the generic class EfEntityRepositoryBase are defined with the same generic parameter type Product. Since those teaching examples are not set in context of real application code, their real intentions or ideas behind them are not easy to understand.
As a side note, you should know that in case the class EfEntityRepositoryBase<TEntity> would be defined with a different generic parameter type than Product e.g., int, ProductDal would have two implementations/member overloads of the IEntityRepository<T> interface.
For example:
public class ProductDal : EfEntityRepositoryBase<int>, IProductDal
{
// Implementation of IProductDal. The EfEntityRepositoryBase type provides another 'int' overload
public void Add(Product entity) {}
}
void Main()
{
var productDal = new ProductDal();
// Implementation of IEntityRepository<int> provided by class EfEntityRepositoryBase<int>
productDal.Add(6);
// Implementation of 'IProductDal' (provided by class 'ProductDal')
productDal.Add(new Product());
}
You can see that your provided example shows a special case where the EfEntityRepositoryBase<TEntity> already provides the implementation for the IEntityRepository<Product> and the IProductDal interfaces.
Back to your example: if you make use of type casting, you will find another use case for having the alledgedly redundant type definitions:
Given is your ProductDal type with the following class signature
public class ProductDal : EfEntityRepositoryBase<int>, IProductDal
You have now multiple types available to access the implementation of IEntityRepository<Product>
void Main()
{
// Create an instance of ProducDal
ProductDal productDal = new ProductDal();
/* Use the instance of ProductDal with multiple overloads
to show implicit type casting */
UseProductDal(productDal);
UseIProductDal(productDal);
UseIEntityRepository(productDal);
UseEntityRepository(productDal);
}
void UseProductDal(ProductDal productDal)
{
// Instantiate the argument
var product = new Product();
productDal.Add(product);
}
void UseIProductDal(IProductDal productDal)
{
// Instantiate the argument
var product = new Product();
productDal.Add(product);
}
void UseIEntityRepository(IEntityRepository<Product> productDal)
{
// Instantiate the argument
var product = new Product();
productDal.Add(product);
}
void UseEntityRepositoryBase(EntityRepositoryBase<Product> productDal)
{
// Instantiate the argument
var product = new Product();
productDal.Add(product);
}
This shows how to make use of the implicit type casting and also how to use interfaces.
You now see that although EntityRepositoryBase<Product> already implements IEntityRepository<Product>, still having ProductDal additionally implement the IProductDal interface makes perfect sense in order to enable ProductDal to be used where only the IProductDal interface is known.
You can make use of interface casting to hide members. For example if you add exclusive members to each interface then this members are only accessible when casting the implementor to the corresponding interface:
public interface IEntityRepository<T>
{
void Add(T entity);
}
public interface IProductDal: IEntityRepository<Product>
{
// Exclusive member. Will be only visible when accessed through this interface.
int GetProductCount();
}
Given is your ProductDal type with the following class signature
public class ProductDal : IEfEntityRepository<int>, IProductDal
void Main()
{
// Create an instance of ProducDal
ProductDal productDal = new ProductDal();
/* Use the instance of ProductDal with multiple overloads
to show implicit type casting */
UseProductDal(productDal);
UseIProductDal(productDal);
UseIEntityRepository(productDal);
UseEntityRepository(productDal);
}
// All implemented interfaces are visible since there is no casting involved.
// All members are referenced via the implementor type ProductDal.
void UseProductDal(ProductDal productDal)
{
// Instantiate the argument
var product = new Product();
productDal.Add(product);
int productCount = productDal.getProductCount();
}
// Only 'IProductDal' is visible since there is an implicit cast to an interface type involved
void UseIProductDal(IProductDal productDal)
{
// Instantiate the argument
var product = new Product();
// 'Add()' is provided by 'IEntityRepository<T>',
// which is implemented by 'IProductDal' and therefore "visible"
productDal.Add(product);
// 'GetProductCount()' is provided by 'IProductDal'
int productCount = productDal.GetProductCount();
}
// Only 'IEntityRepository<T>' is visible since there is an implicit cast to the interface type
void UseIEntityRepository(IEntityRepository<Product> productDal)
{
// Instantiate the argument
var product = new Product();
productDal.Add(product);
// 'GetProductCount()' is only available via the 'IProductDal' interface.
// It's not visible here.
//int productCount = productDal.GetProductCount();
}
At the root of this question is how interfaces are used in dependency injection and mocking / unit testing.
Let's look at what each of these classes and interfaces give you...
ProductDal
This class contains the logic for interacting with Product instances held in your data store.
IProductDal
Where you want to use a ProductDal to interact with Product instances in your data store, declaring it as a IProductDal instead allows your unit tests for code which is dependent on ProductDal to create mock instances of IProductDal which behave however is needed for your unit tests, so that your unit tests for code which uses ProductDal aren't dependent on an actual database. In your production code you can use dependency injection to inject a real ProductDal where an IProductDal is declared.
IEntityRepository
This looks like a fairly generic interface specifying some basic CRUD operations which might be useful for any entity which you might hold in a data store, and it's agnostic of what the type of data store is (e.g. SQL server / MongoDB / Cassandra / imp with a filing cabinet full of notebooks) or what Object Relational Mapper (e.g. Entity Framework / NHibernate) you might be using to access the data store.
EfEntityRepositoryBase
This abstract class contains an implementation of the basic CRUD methods in IEntityRepository which is specific to Entity Framework, to save you repeating those methods in your ProductDal etc classes. You could have another abstract class with implementations of those methods for another ORM (e.g. NHibernate), and if you were to switch from using Entity Framework to using NHibernate then you'd just need to change the inheritance of each of your ProductDal etc classes so that they derive from NHibernateEntityRepository<T> rather than EfEntityRepositoryBase<T>.
But back to the question...
I can't understand the point of IProductDal implementing IEntityRepository, since ProductDal already inherits the abstract base class that implements the same interface
If you're using ProductDal rather than IProductDal wherever you want to interact with Product instances in your data store, then it doesn't really make any difference in your production code, but your unit tests are going to be really difficult to write, and probably slow to run and rather flaky too, because they'll depend on a real data store which is in exactly the right state at the start of each test case.
If instead you're using IProductDal to interact with Product instances in your data store, and using dependency injection to use a ProductDal where a IProductDal is needed by your production code (so that unit tests for that code aren't dependent on a real data store), you'll hit a different problem. Consider this unit test (which uses the Moq mocking framework, but the same issue exists regardless of what mocking framework you use):
[Fact]
public void Test1()
{
var mockProductDal = new Mock<IProductDal>();
mockProductDal.Setup(m => m.GetAll(null))
.Returns(new List<Product> { new Product { } });
}
In the above test, the compiler only understands m => m.GetAll if IProductDal is derived from EfEntityRepositoryBase (which is where the GetAll method is defined).
Similar problems will also turn up in any of your production code which uses IProductDal - after all, that code is a consumer of IProductDal / ProductDal in the same way that the above unit test is.
In short...
Reference the interface rather than the implementation in your production code. Use dependency injection in your production code to inject the real implementation, and mock the interface in your unit tests to remove dependencies on external resources such as data stores. If you do this then you also need to do apparently strange things like making Interface1 implement Interface2 when the class which implements Interface1 is derived from a class which implements Interface2. But it'll make your unit tests easier to write, and better, and better unit tests can only be a good thing.
We have an interface to deal with DAL with pretty simple definition:
interface IRepository<T> : IQueriable<T> // so we can read data from database
{
Save(T document); // dozen of methods here
}
Mostly we use two implementations: real version and in memory version for unit testing. Here is declarations of one of class:
public RealRepository : IRepository<AccountEntity> { ... }
// typical IOC usage
services.AddSingleton<IRepository<AccountEntity>, RealRepository<AccountEntity>>();
Now we are working to spin off for main codebase to custom version of project and we need custom fields in data and occassional custom behavior in repository. Most of classes are fine with base implementation but others would require specific implementation. So my goal is to get to following services in:
var repository = new RealRepository<CustomAccountEntity>();
services.AddSingleton(IRepository<AccountEntity>, repository);
// for new classes
services.AddSingleton(IRepository<CustomAccountEntity>, repository);
I tried to add out T to IRepository but I am using T in input parameters and this gave compile time "Invalid variance" error.
I can see a solution by adding second type parameter to interface so it looks like:
IRepository<TBase, out TChild> : IQueriable<TChild> {
Save (T document);
}
Finally, Question: How can make change 100% backward compatible?
What I tried:
Add IRepository<T>: IRepository<T,T> -> complies, but RealRepository is not implementing IRepository anymore.
Add 2 interfaces in implementation: public class RealRepository<TBase, TChild>: IRepository<TBase, TChild>, IRepository<TChild> but this gives compliation error 'cannot implement both ... and ... because they may unify for some type parameter substitutions'
Save(T document) has T in a contravariant position. That means in T, not out T.
Let's recap what contravariance means. Suppose you had this code:
using System;
public class Entity {}
public class AccountEntity : Entity {}
public class CustomAccountEntity : AccountEntity {}
public interface IQueryable<in T>
where T : Entity
{}
public interface IRepository<in T>
where T : Entity
{
void Save(T record);
}
public class EntityRepository<T> : IRepository<T>
where T : Entity
{
public void Save(T record) {}
}
public class Program
{
public static void Main()
{
// This is ***VALID***:
IRepository<CustomAccountEntity> repo = new EntityRepository<AccountEntity>();
Console.WriteLine(repo == null ? "cast is invalid" : "cast is valid");
}
}
https://dotnetfiddle.net/cnEdcm
So whenever you need a IRepository<CustomAccountEntity>, you can use a concrete EntityRepository<AccountEntity> instance. Seems counter-intuitive, but it's actually totally right: If the concrete method is Save(AccountEntity), it can obviously handle CustomAccountEntity instances too; OTOH if the concrete method were Save(CustomAccountEntity), it would NOT be able to handle simple AccountEntity instances.
Having said that, then I think you should
Use contravariance instead;
Declare all dependencies using the most specialised type, e.g. IRepository<CustomWhateverEntity>;
In the IoC registration code, for each particular entity, setup either Repository<CustomeWhateverEntity>, if you need the extra behaviour, or just Repository<WhateverEntity> otherwise.
I'm having trouble with getting generics and DI to work together in an MVC Core project. I have a generic class (this is just a fragment). I need to initialize Input and Output because of how these are used in other parts of the code, so I'm using Activator to provide initial values and the new() constraint.
public class Message<TIn, TOut> :
where TIn : class, IMessagePart, new()
where TOut : class, IMessagePart, new() {
public Message(){}
public Message(TIn inpart, TOut outpart) {
Input = inpart;
Output = outpart;
}
public TIn Input { get; set; } = (TIn)Activator.CreateInstance(typeof(TIn));
public TOut Output { get; set; } = (TOut)Activator.CreateInstance(typeof(TOut));
}
I have other classes that are used by this, and they have some static utility classes. I'm trying to replace these static classes using DI.
public class Project : IMessagePart{
int y = 1;
var x = StaticUtilityClass.StaticMethod(y);
}
is used like this
var projectMessage = new Message<Project, Project>();
I'm converting the static utility classes to instance classes and injecting them. I'm using the built-in .Net core container. I converted the utilities to instance classes and registered them as concrete singletons in the container. For most things I can just do the normal-
public class SomeClass{
private readonly UtilityClass _utility;
public SomeClass(UtilityClass utility){
_utility = utility;
var x = _utility.Method(1);
}
Things work fine until I get to the generics. I can't do constructor injection on projectMessage, because the generic needs to new it up and it has the new() constraint, so I need a parameterless constructor. If I add just the an injecting constructor I get
'Project' must be a non-abstract type with a public parameterless
constructor in order to use it as parameter 'TIn' in the generic type
or method 'Message'.
and if I add both constructors Activator is only going to call the one without parameters, so DI isn't invoked. I tried using the overload of CreateInstance a few different ways, but no luck tricking it.
Any suggestions here? I don't know if I should stay with statics, try some sort of service locator approach, or if there is a different way to writing the generic.
The answer to why you are getting the error you're seeing is the new() constraints. That specifies that the parameter must have a public parameterless constructor. Which is exactly what your error says. Removing that constraint should fix that error. However, you still have another issue if you want to use DI.
Aside from IMessagePart none of your classes have backing interfaces. In order to use DI effectively you need to define an IMessage, IProject etc. Then your container can create specific instances at runtime, rather than using the Activators like you are now. So your Message declaration would look like:
public class Message<TIn, TOut> : IMessage,
where TIn : class, IMessagePart
where TOut : class, IMessagePart
{
public TIn input { get; set; }
public TOut output { get; set; }
public Message(TIn inpart, TOut outpart) {
this.input = inpart;
this.output = outpart;
}
}
You would setup your DI container something like:
public Startup()
{
var container = new DiContainer(); // I know this is the wrong name; I'm not familiar with the built in container naming and functionality.
container.Register<IMessage>();
container.Register<IMessagePart>();
container.Register<IProject>();
// Register other stuff here
}
Change the syntax there for your specific container. You also have the option of registering your instances something like:
container.Register<Message>(() => Message(part1, part2));
so that you specifically inject a Message that is newed up at Startup time, but that's not really ideal in most cases. Usually you want your DI container to dynamically create an instance as needed (hence the interfaces), rather than using a single concrete instantiation. There are exceptions of course; a SQL connection is one common one.
I have a generic class that deals with widgets that can be deserialized from strings. Instances of the generic class will take the type of one of these widgets as a template parameter, and then create these widgets from strings. I wish to use the covariance properties of C#'s generics to write code like WidgetUser<IWidget> to deal with objects that may be WidgetUser<RedWidget> or WidgetUser<BlueWidget>. The problem is that to create a widget from a string inside of WidgetUser<T>, I'm forced to add new() as a guard. This makes WidgetUser<IWidget> an invalid type. Currently, I have code like this:
interface IWidget
{
// Makes this widget into a copy of the serializedWidget
void Deserialize(string serializedWidget);
}
class WidgetUser<T> where T : IWidget, new()
{
public void MakeAndUse(string serializedWidget)
{
var widget = new T();
widget.Deserialize(serializedWidget);
Use(widget);
}
}
With this code, I can make WidgetUser<BlueWidget> just fine, because BigWidget satisfies new(). I cannot write WidgetUser<IWidget> because instances of IWidget (or an equivalent abstract class) are not guaranteed to work with new(). A workaround could be this:
abstract class WidgetUser
{
public abstract void MakeAndUse();
}
class WidgetUser<T> : WidgetUser
where T : IWidget, new()
{
/* same as before but with an 'override' on MakeAndUse */
}
With this code, I can create a WidgetUser<BlueWidget> then write code that deals with just WidgetUser. I could have similar code with an abstract class BaseWidget instead of IWidget that accomplishes almost the same thing. This is functional, but I suspect there is a more direct approach that doesn't force me to define a dummy class. How can I convey my intent to the type system without creating dummy classes or extra factories. I just want an interface that says "you can make one of these from a string".
TL;DR:
Is there some way to write an interface or abstract class that lets me create an instance from a string but doesn't require me to have new() as a guard on WidgetUser<T>?
The problem here is that your Deserialize() method should be a static method. Therefore it should not be a member of IWidget itself - it should be a member of a factory interface, or it should be a static member of a concrete Widget class which is called from a concrete factory method. I show the latter approach below.
(Alternatively, you could use a Func<IWidget> delegate to specify it, but it's more usual to provide a full factory interface.)
So I suggest you create the factory interface:
interface IWidgetFactory
{
IWidget Create(string serialisedWidget);
}
Then remove the Deserialize() from IWidget:
interface IWidget
{
// .. Whatever
}
Then add a static Deserialize() method to each concrete implementation of IWidget:
class MyWidget: IWidget
{
public static MyWidget Deserialize(string serializedWidget)
{
// .. Whatever you need to deserialise into myDeserializedObject
return myDeserializedObject;
}
// ... Any needed IWidget-implementing methods and properties.
}
Then implement the factory for your concrete widget class using the static Deserialize() method from the concrete widget class:
sealed class MyWidgetFactory : IWidgetFactory
{
public IWidget Create(string serialisedWidget)
{
return MyWidget.Deserialize(serialisedWidget);
}
}
Then add a constructor to your WidgetUser class which accepts an IWidgetFactory and use it in MakeAndUse():
class WidgetUser
{
public WidgetUser(IWidgetFactory widgetFactory)
{
this.widgetFactory = widgetFactory;
}
public void MakeAndUse(string serializedWidget)
{
var widget = widgetFactory.Create(serializedWidget);
Use(widget);
}
private readonly IWidgetFactory widgetFactory;
}
Note that in this scenario, you no longer need the type argument for WidgetUser, so I have removed it.
Then when you create the WidgetUser you must supply a factory:
var widgetUser = new WidgetUser(new MyWidgetFactory());
...
widgetUser.MakeAndUse("MySerializedWidget1");
widgetUser.MakeAndUse("MySerializedWidget2");
Passing in a factory allows a lot more flexibility.
For example, imagine that your serialization scheme included a way of telling from the serialized string which kind of widget it is. For the purposes of simplicity, assume that it starts with "[MyWidget]" if it's a MyWidget and starts with ["MyOtherWidget"] if it's a MyOtherWidget.
Then you could implement a factory that works as a "virtual constructor" that can create any kind of Widget given a serialization string as follows:
sealed class GeneralWidgetFactory: IWidgetFactory
{
public IWidget Create(string serialisedWidget)
{
if (serialisedWidget.StartsWith("[MyWidget]"))
return myWidgetFactory.Create(serialisedWidget);
else if (serialisedWidget.StartsWith("[MyOtherWidget]"))
return myOtherWidgetFactory.Create(serialisedWidget);
else
throw new InvalidOperationException("Don't know how to deserialize a widget from: " + serialisedWidget);
}
readonly MyWidgetFactory myWidgetFactory = new MyWidgetFactory();
readonly MyOtherWidgetFactory myOtherWidgetFactory = new MyOtherWidgetFactory();
}
Note that this is generally not the best way to do things - you are better using a Dependency Container such as Autofac to manage this kind of thing.
I would implement WidgetFactory and call WidgetFactory.Create<T>(serializedWidget) to avoid the usage of new T()
So, I'm making a generic provider for my repositories implementation which will be used by my BaseController (ASP.NET MVC 2) for low-level objects. These objects have common operations, such as Activate/Deactivate/Delete/Edit, so I'll always be working with the same property on each. The problem is, since I don't know what T is, I obviously don't have access to its properties.
So, my question is, can someone show me how to get the properties I need out of the objects. I've seen some people talking about Reflection, others Expression Trees, neither of which I know how to use.
I do have a generic repository which I believe uses Expression Trees (copied it from some website), but again, I don't know what I'm doing with it... If it helps, here's what I've got so far:
public class Provider<T> where T : class {
private readonly Repository<T> Repository = null;
public Provider(
Repository<T> Repository) {
this.Repository = Repository;
}
public void Activate(
int Id) {
T Entity = this.Repository.Select(Id);
// Need to get the property here, change it and move on...
this.Repository.Submit();
}
}
I'd appreciate any help on this.
If those classes have common operations, sounds like they should inherit from the same base or implement the same interface, correct? If so, use that interface/base as the constraint for T
public class Provider<T> where T : ICommonInterface
You will then have compile-time access to the shared members provided by the interface or base class.
You could make an action
public void Activate(int Id, Action<T> doSomething)
{
T Entity = this._repository.Select(Id);
// Need to get the property here, change it and move on...
doSomething(Entity);
_repository.Submit();
}
Then using the Action delegate (in this example via a lambda) the properties will be known when activate is called:
prov.Activate(5, x => x.Address = "fgfgf");
The best solution will be to give the objects a common base type, and constrain the type parameter T to be of that type. Then you'll have access to the methods or properties of the common base type at compile time:
public class Provider<T> where T : ICommon
{
...
}
or
public class Provider<T> where T : CommonBase
{
...
}
If that's not possible, then without a common base type the best you can do is reflect upon the objects to look for and invoke the property that you are interested in:
public void Activate(int Id)
{
T entity = this.Repository.Select(Id);
// Interrogate the type of the entity and get the property called "MyPropertyName"
PropertyInfo pi = entity.GetType().GetProperty("MyPropertyName");
// Invoke the property against the entity instance - this retrieves the
// value of the property.
var value = (YourType)(pi.GetValue(entity, null));
// Do somethign with the value...
this.Repository.Submit();
}
I should add that reflection is comparatively expensive and you also lose the compile time verification. But it's handy in cases like these.
You can get a MethodInfo object for working with methods by calling:
MethodInfo mi = entity.GetType().GetMethod("MyMethodName");