In .NET Core, I am getting the issue of dependency resolution.
I have the following class hierarchy.
public abstract class TestBaseConfigs
{
//some base configs
}
public class ChildDfx1Configs : TestBaseConfigs
{
//some specific child configs.
}
public class ChildDfx2Configs : TestBaseConfigs
{
//some specific child configs2
}
public interface ITest<T>
{
void Calculate();
}
public class Dfx1Calc : ITest<ChildDfx1Configs >
{
void Calculate() //implemented method from interface
{
}
}
public class Dfx2Calc : ITest<ChildDfx2Configs>
{
void Calculate() //implemented method from interface
{
}
}
var currencyExchangeSettings = Configuration.GetSection("DfxCurrencyExchangeSettings");
var useDfx1CurrencyExchange = currencyExchangeSettings["UseDfx1CurrencyExchange"];
if (Convert.ToBoolean(useDfx1CurrencyExchange))
{
services.AddScoped<ITest<ChildDfx1Configs>, Dfx1Calc>(); not works..
services.AddScoped<ITest<TestBaseConfigs>, Dfx1Calc>(); //this also doesn't work as well.
}
and the constructor of class where the above dependency needed to be passed in.
public TranslationFeeManager(IChargesRepository chargesRepository, ITest<TestBase> currencyConversionManager)
{
_chargesRepository = chargesRepository;
_currencyConversionManager = currencyConversionManager;
}
Somehow ITest does not resolved. Dont know why. What could be the reight solution?
Can any body help me here ?
Thanks.
Did you mean Dfx1Calc instead of DfxCalc when adding services?
Related
I am getting CS0175 Use of keyword 'base' is not valid in this context error in my unit test case project.
This is how my code looks:
A class which implements a interface
public interface iUtility
{
void Print();
}
public class Utility: iUtility
{
public void Print()
{
Console.Write("Print");
}
}
A base class which uses the utility class and a derived class
public class BaseCls
{
private iUtility _iUtility;
public BaseCls()
{
_iUtility = new Utility();
}
public BaseCls(iUtility iUtility)
{
_iUtility = iUtility;
}
}
public class DerivedCls : BaseCls
{
public void PrintSomething()
{
Console.Write("Print Something");
}
}
In my unit test project, I am testing derived class and trying to pass the instance of utility class. Why I am doing this may not make sense now but I am planning to use unity framework and use IoC to inject different dependencies.
I am not showing all code for brevity.
Error is happening in unit test project
[TestClass]
public class UnitTest1
{
public void TestInitialize()
{
//I want to pass instance of utility class here
iUtility obj = new Utility();
DerivedCls cls = new DerivedCls(): base(obj);
}
[TestMethod]
public void TestMethod1()
{
}
}
What do I need to do to fix this error? I want to pass the instance of utility class from derived class through constructor.
You need to provide a constructor in your derived class.
public class DerivedCls : BaseCls
{
public DerivedCls(iUtility utility) : base(utility) { }
}
Then construct your DerivedCls instances as you normally would: new DerivedCls(someIUtilityInstance)
Currently I am in the phase of refactoring my code after it has been unit tested, and I have some concerns about the refactoring from a design point of view with regards to type safety. My original code looked a bit like this:
Interfaces
public interface IBase
{
int ID { get; set; }
}
public interface IFirstSub : IBase
{
string Description { get; set; }
}
public interface ISecondSub : IBase
{
decimal Total { get; set; }
}
public interface IThirdSub : IBase
{
int Count { get; set; }
}
public interface IBaseContainer
{
void Add(IBase baseParam);
}
Implementations
public class FirstContainer : IBaseContainer
{
public void Add(IBase baseParam)
{
if (!(baseParam is IFirstSub || baseParam is ISecondSub))
{
throw new ArgumentException(nameof(baseParam));
}
// Do Something
}
}
public class SecondContainer : IBaseContainer
{
public void Add(IBase baseParam)
{
if (!(baseParam is IThirdSub))
{
throw new ArgumentException(nameof(baseParam));
}
// Do Something
}
}
With my original implementation of FirstContainer and SecondContainer, it was repeating the same logic at the start of the Add method, so I thought I would refactor the code to look something like this:
public abstract class BaseContainer : IBaseContainer
{
private readonly List<Type> _types = new List<Type>();
protected BaseContainer(params Type[] baseTypes)
{
_types.AddRange(baseTypes);
}
public void Add(IBase baseParam)
{
if (_types.All(type => !type.IsInstanceOfType(baseParam)))
{
throw new ArgumentException(nameof(baseParam));
}
DoSomething(baseParam);
}
protected abstract void DoSomething(IBase baseParam);
}
public class ThirdContainer : BaseContainer
{
public ThirdContainer() : base(typeof(IFirstSub)) { }
protected override void DoSomething(IBase baseParam)
{
// Do Something
}
}
With this refactoring done, it successfully removes the duplication of the code from the start of the Add method, but my main concern with the refactoring is the fact that the call to the base constructor base(typeof(IFirstSub)) is not really type safe. By that, I mean I can call the base constructor like base(typeof(object)) for example, and it will compile. For the purposes of my project, I'd like to constrain the types to ones that inherit IBase, and enforce at compile time.
Is there anyway to overcome this limitation, or would a new design be needed in order to achieve this?
No it's not type safe
Passing and validating types at run-time is not type-safe, as type-safety is a compile-time concept. In my opinion your refactoring effort does not improve the code, and in fact does something quite weird.
Function overloading
If you need a method that accepts either of two types, you can use function overloading:
public class FirstContainer : IBaseContainer
{
public void Add(IFirstSub param)
{
// Do Something
}
public void Add(ISecondSub param)
{
// Do Something
}
}
The compiler will automatically choose the right prototype for you, and will not allow anything other than an IFirstSub or ISecondSub.
Create another interface
Another approach requires you to add an interface for the types that have something in common, like this:
interface ICanBeHeldInFirstContainer
{ }
public interface IFirstSub : IBase, ICanBeHeldInFirstContainer
{
string Description { get; set; }
}
public interface ISecondSub : IBase, ICanBeHeldInFirstContainer
{
decimal Total { get; set; }
}
Then you do this:
public class FirstContainer : IBaseContainer
{
public void Add(ICanBeHeldInFirstContainer param)
{
// Do Something
}
}
or this:
public class FirstContainer : IBaseContainer
{
public void Add<T>(T param) where T : ICanBeHeldInFirstContainer
{
// Do Something
}
}
I am writing a tranformer that takes some input and gives an output.I need to call a specific tranformer based on my input type.
public static myentrypoint( template t);
{
//I could do something like this.
switch(t)
{
case t1:
transformt1(..);
case t2:
transformt1(..);
....
}
}
Trasform1 : Itransform
{
tranform1(...);
}
Trasform2 : Itransform
{
tranform2(...);
}
I need to map which function to call based on what my template is. I can do a switch but are there more cleaner ways to do this using some design patterns ? I was thinking a of writing a static dictionary. I am new to OOP so any suggestions would be great.
If template is a class, and each template potentially has a different transform, then why not just include the transform function inside of your template class?
public static myentrypoint( ITemplate t);
{
t.transform();
}
The way that I do these types of situations is through the use of Generics. (Shameless self-promotion of a blog post)
Basically, you'll have your base class set up like this:
public abstract class Transformer<T>
where T : Template
{
public abstract void Transform(T item);
}
Then you derive for each of your types like this:
public class Transformer1 : Tansformer<Template1>
{
public void Transform(Template1 item)
{
}
}
public class Transformer2 : Transformer<Template2>
{
public void Transform(Template2 item)
{
}
}
Then you'll just need a factory to give you the correct Transformer.
public class TransformFactory
{
public Transformer<T> GetTransformer<T>(T item)
{
if (item is Template1)
return new Transformer1();
else if (item is Template2)
return new Transformer2();
// ...
}
}
The benefit of this approach is that you'll be able to encapsulate all behavior on that specific type in the concrete implementations. If there is any common behavior on them all, you can do that in the abstract base.
Invoking methods based on a parameter without switch-case statements in C#
In OOP, based on the [open/close principle] which says that software entities such as classes and functions should be open for extension, but closed
for modification.
Methods which use switch-case statement would call this principle into question. In order to implement this principle inside the codes without
causing changes in their functionality.
We use a pattern named "Delegate Dictionary Pattern".
For example, we have an entity named Template that keep input values as well as some of Transform classes for processing this Template.
Template class for keeping input value
public class Template
{
public int TransformNo { get; set; }
public string Title { get; set; }
}
ITransform interface for transform abstract
public interface ITransform
{
void Do(Template template);
}
Transform1 as a concrete class of ITransform
public class Transform1 : ITransform
{
public void Do(Template template)
{
Console.WriteLine($"Transform : {template.TransformNo}, TemplateTitle : { template.Title}");
}
}
Transform2 as a concrete class of ITransform
public class Transform2 : ITransform
{
public void Do(Template template)
{
Console.WriteLine($"Transform : {template.TransformNo}, TemplateTitle : { template.Title}");
}
}
TransformCordinator class for coordinating template of *ITransformer**
public class TransformCordinator
{
Dictionary<int, Action<Template>> transformMap = new Dictionary<int, Action<Template>>();
public TransformCordinator()
{
transformMap.Add(1, x => new Transform1().Do(x));
transformMap.Add(2, x => new Transform2().Do(x));
}
public void Do(Template template)
{
transformMap[template.TransformNo](template);
}
}
// example
class Program
{
static void Main(string[] args)
{
var transformCordinator = new TransformCordinator();
transformCordinator.Do(new Template() { TransformNo = 1, Title = "Hi!" });
Console.ReadLine();
}
}
I have these classes:
public class BaseGame<T> where T : BaseQuestion
{
//some fileds and methods
}
public class BaseQuestion
{
//some fileds and methods
}
public class Question : BaseQuestion
{
//some fileds and methods
}
public class SampleGame : BaseGame<Question>
{
//some fileds and methods
}
Whenever i want to cast BaseGame to SampleGame i get Error.
void SetValue(BaseGame<BaseQuestion> _game)
{
SampleGame = (SampleGame) _game;
}
Cannot implicitly convert type BaseGame to SampleGame.
How To Fix this?
Thanks.
Change your code to this:
public interface IBaseGame<out T> where T : BaseQuestion
{
}
public class BaseGame<T> : IBaseGame<T>
where T : BaseQuestion
{
}
public class BaseQuestion
{
}
public class Question : BaseQuestion
{
}
public class SampleGame : BaseGame<Question>
{
}
And then your method:
void SetValue(IBaseGame<BaseQuestion> _game)
{
var SampleGame = (SampleGame) _game;
}
Why was your code broken?
You cannot do the cast because BaseGame was not covariant. This means that the compile cannot gaurantee that the cast is safe. Take for example, the following example:
public class BaseGame<T> where T : BaseQuestion
{
private List<T> Questions { get; set; }
public void AddQuestion(T question) { Questions.Add(question); }
}
var game = new BaseGame<Question> { Questions = new List<Question> };
game.AddQuestion(new Question());
Okay, so now your game has a list of Question, with one question in it. Now let's cast it:
public class BrokenQuestion : BaseQuestion
{
}
public class BrokenGame : BaseGame<BrokenQuestion>
{
}
var brokenGame = (BrokenGame)game;
brokenGame.Add(new BrokenQuestion());`
Oops! We just added a BrokenQuestion to a List<Question>. No good.
Defining the template argument as out T instead of T means we're making a contract that we will not accept sub classes of T, but we can return them. This means that it's now illegal to expose AddQuestion(T question). Now, the compiler can be sure that there will never be a BrokenQuestion added to List<Question>.
For more information, see here
I had a question on C# generics. I wish to store a generic type variable in my abstract class without declaring that type outside the class.
Below is the code sample. Please note that I do not wish to make the Param classes exposed outside the Calc class.
Thanks in advance.
- Dutta.
abstract class Base { }
abstract class Calc<T> where T : Base
{
protected Param Member; /* how can this be a made a generic declaration
* WITHOUT declaring this class like,
* class Calc<T, P>
* where T : Base
* where P : Param */
protected Calc(Param p)
{
this.Member = p;
}
protected abstract class Param { }
}
class MyBase : Base { }
class MyCalc : Calc<MyBase>
{
public MyCalc() : base(new MyParam()) { }
public void doSomething()
{
base.Member.A++; // fails on compilation
}
private class MyParam : Calc<MyBase>.Param
{
public int A;
public MyParam() { this.A = 0; }
}
}
You just need to cast it to the new type, because no matter what, the variable Member was declared as Param and it will always be accessed as Param:
((MyParam)base.Member).A++;
Secondly, you can fix up your MyParam class by changing from this:
MyParam : Calc<MyBase>.Param
To this:
MyParam : Param
Because Param is already Calc<MyBase> through generics and inheritance.
Thraka's answer is correct: if you don't want to use generics you need to cast. Just to add to it, in case what you're really trying to do looks something like this. Here's a set of classes that you can expose from your library, which will not be extensible by clients (unless they're running with full trust and can use reflection etc.!!) but which can be used in a type-safe way.
public abstract class SupportedPaymentMethod
{
protected internal SupportedPaymentMethod() { }
}
public sealed class Check : SupportedPaymentMethod
{
public int CheckNumber { get; private set; }
public Check(int checkNumber)
: base()
{
CheckNumber = checkNumber;
}
}
public sealed class CreditCard : SupportedPaymentMethod
{
public CreditCard()
: base()
{ }
}
public abstract class Payment<T>
where T : SupportedPaymentMethod
{
public T Method { get; private set; }
protected internal Payment(T method)
{
Method = method;
}
}
public sealed CheckPayment : Payment<Check>
{
public CheckPayment(Check check)
: base(check)
{ }
}
public sealed CreditCardPayment : Payment<CreditCard>
{
public CreditCardPayment(CreditCard creditCard)
: base(creditCard)
{ }
}
Clients (i.e. code outside of your class library's assembly) will be able to instantiate a CheckPayment or a CreditCardPayment, but they will not be able to create a new class deriving from Payment<T>. So, it will not be possible for clients to create a CheatingPaymentMethod : Payment<Cheating>, for example. :)
Calls like your intended call to base.Member.A++ will now work:
var checkPayment = new CheckPayment(new Check(123456));
var checkNumber = checkPayment.Method.CheckNumber; // Success! :)