2

I have created this interface based on documentation given to me. (I need to work with a third party API for database logging). I am expected to return the object type "Logger" for the getLogger() method and object type "DatabaseMgr" for the getDatabaseMgr method. However, these are abstract classes. The documentation did not specify what the method does, they simply wrote {...}.

If I cannot create an instance of those classes, then how can I return them?

using System;
using System.Data.Common;

namespace com.XXXXXXXXXX.api
{
    public class ApiFactory
    {
        public static ApiFactory getInstance() {
            return new ApiFactory();
        }


        public Logger getLogger(String Id, Type type)
        {
        }

        public DatabaseMgr getDatabaseMgr(String Id)
        {
        }

    }
    public abstract class Logger
    {
        public String Id { get; set; }
        public abstract void trace(String message);
        public abstract void debug(String message);
        public abstract void info(String message);
        public abstract void warn(String message);
        public abstract void error(String message);
        public abstract void alert(String message);
        public abstract bool isTraceEnabled { get; }
        public abstract bool isDebugEnabled { get; }
        public abstract bool isInfoEnabled { get; }
        public abstract bool isWarnEnabled { get; }
        public abstract bool isErrorEnabled { get; }
    }
    public abstract class DatabaseMgr
    {
        public String Id { get; set; }

        protected DatabaseMgr(String Id)
        {
        }

    }
}
2
  • 2
    If they didn't provide concrete implementations of the abstract classes then you can always create your own and return instances of them. Commented Dec 23, 2015 at 17:18
  • First you have to create two new non-abstract classes which derive from Logger and DatabaseMgr respectively and then return objects of those newly created classes. Commented Dec 23, 2015 at 17:29

4 Answers 4

13

The word "abstract" means that you can't create an instance of this class. You can make another class that inherits from the abstract class and create instances from the child (non-abstract) class.

Sign up to request clarification or add additional context in comments.

Comments

2

Your abstract class must be implemented in a derived class:

public abstract class Logger
{
    public abstract void debug(String message);
    //Other properties and methods
}

MyLoggerImpl is the derived class of abstract Logger, optionally apply MyLoggerImpl with sealed modifier to prevent other classes from inheriting:

public sealed class MyLoggerImpl : Logger
{
    public override void debug(string message) 
    {
        //Write log
        //Trace.WriteLine(message);
    }
}

Now create the instance of MyLoggerImpl in another class MyLogger: I'd prefer to create debug() as static, so that only one copy of a static member exists, regardless of how many instances of the class are created, also avoiding create the instance of MyLogger several times from different code modules, instead MyLogger.debug("Some message.") can be called:

public class MyLogger
{
    public static void debug(string message)
    {
        var log = new MyLoggerImpl();
        log.debug(message);
    }
}

MSDN reference is here:

Sample usage from a console application:

static void Main(string[] args)
{
    MyLogger.debug("Some message.");
}

Comments

2

For .NET Core 3.1 and .NET 5 you could use System.Reflection

Add constructor to Logger:

public abstract class Logger
{
    public Logger() { }
    public String Id { get; set; }
    public abstract void trace(String message);
    ...
    ...
    public abstract bool isWarnEnabled { get; }
    public abstract bool isErrorEnabled { get; }
}

Use reflection to get instance:

Type typeLogger = typeof(Logger);
ConstructorInfo magicConstructor = typeLogger.GetConstructor(Type.EmptyTypes);//get Constructor

Type TypeRuntimeMethodHandle = typeof(RuntimeMethodHandle);
MethodInfo magicMethod = TypeRuntimeMethodHandle.GetMethod("InvokeMethod", BindingFlags.Static | BindingFlags.NonPublic);//get InvokeMethod from RunTimeMethodHandle

PropertyInfo sigInfo = magicConstructor.GetType().GetProperty("Signature", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance);//get signature
Logger abstrObj = (Logger)magicMethod.Invoke(null, new object[] { null, null, sigInfo.GetValue(magicConstructor), true , null});

abstrObj.Id = "2366";
Console.WriteLine(abstrObj.Id);
Console.WriteLine(abstrObj.GetType().ToString());

Source: https://github.com/FORzzMOK/Creating-an-abstract-class

Comments

0

Abstract classes are meant to serve as default behavior providers and not for instantiation. So you need to inherit from abstract class get the deafult behaviors of the clan and then extend your inherited class with specific behaviours and states.

In your case you would need to create a reference of the parent abstract class and instantiate your own inherited class and assign it to the reference created above. Now you can return this abstract class reference.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.