As i have this child class defined below.
internal class ParserZillowForSale : Parser
{
public ParserZillowForSale(int threadsCount)
: base(threadsCount) {}
}
And have base class defined below.
public class Parser
{
private readonly int _threadsCount;
public Parser(int threadsCount = 10)
{
_threadsCount = threadsCount;
}
}
Now as i'm trying to define Dependency Injection below.
internal class ParserZillowForSale : Parser
{
private readonly List<ListingDetailsData> listings;
private readonly ListingHeader _ListingHeader;
public ParserZillowForSale(int threadsCount)
: base(threadsCount) {}
public ParserZillowForSale(List<ListingDetailsData> listingsD, ListingHeader _ListingHeaderD)
{
listings = listingsD;
_ListingHeader = _ListingHeaderD;
}
}
As i try to call this object.
ParserZillowForSale ParserZillowForSale = new ParserZillowForSale(maxThreads)
It throws an exception and i want to call both with DI and without. Here is the error which i recieve in the PostMan.
"Exception while executing function: ParserZilowForSale -> The type
initializer for 'Parser.ParserZillowForSale' threw an exception. -> No
valid combination of account information found.",
"errorDetails": "Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception
while executing function: ParserZilowForSale --->
System.TypeInitializationException : The type initializer for
'Parser.ParserZillowForSale' threw an exception. --->
System.FormatException : No valid combination of account information
found"
As i don't want to pass multiple arguments on the base keyword so that's why i created another constructor.
Related
Is it necessary to declare a class in 'public ' visibility mode if the class is defining the user defined exception which extends System.exception class in C#?
It entirely dependes on how you want to use your user defined exception class.
The concept of access modifier is not related at all with the idea of a user defined exception.
A user defined exception is just a user defined class which extends System.Exception, while an access modifier is a construct which specifies the visibility of that class with respect to the client code.
This means that if you just want to use your custom exception class inside the defining assembly you can simply define it as an internal class.
Of course this won't be very useful, because you usually define custom exception class inside class libraries and you want them to be visible in any assembly referencing your class library, so that a consumer can have a chance to handle your custom exception class if it makes sense in his or hers client code.
Try it on DotNetFiddle and see:
public class Foo
{
private class MyException : Exception
{
public MyException(string message) : base(message) { }
}
public static void Throw()
{
throw new MyException("Hello world.");
}
}
public class Program
{
public static void Main()
{
try
{
Foo.Throw();
}
//catch(Foo.MyException myException)
//{
// This doesn't compile
//}
catch(System.Exception exception)
{
Console.WriteLine
(
"Exception is of type '{0}' with a message of '{1}'",
exception.GetType().Name,
exception.Message
);
//Does not compile:
//var typedException = (Foo.MyException)exception;
}
}
}
Output:
Exception is of type 'MyException' with a message of 'Hello world.'
So it turns out you can still catch the exception, inspect its type, and read its base properties, and everything works. But if you want to handle it in a type-safe way and cast it to the specific type, your code won't compile. This also means you can't use a type-specific catch handler.
my code look like this
private void installData()
{
var dataInstallServices = new List<IDataInstallationService>();
var dataInstallServiceTypes=_typeFinder.FindClassesOfType<IDataInstallationService>();
foreach (var dataInstallServiceType in dataInstallServiceTypes)
dataInstallServices.Add((IDataInstallationService)Activator.CreateInstance(dataInstallServiceType));
foreach (var installServie in dataInstallServices)
installServie.InstallData();
}
my problem is
dataInstallServices.Add((IDataInstallationService)Activator.CreateInstance(dataInstallServiceType,"parameters resolve using autofac"))
I register all dependency but I am getting No parameterless constructor defined for this object. Exception
If you are using AutoFac you shouldn't need to use Activator to create instances.
Say what you are trying to do above lives in a class called DataService that has the following dependencies:
public class DataInstallerA : IDataInstaller {
public DataInstallerA(SubDependencyA a){}
}
public class DataInstallerB : IDataInstaller {
public DataInstallerA(SubDependencyB b){}
}
With the following AutoFac registrations:
builder.RegisterType<SubDependencyA>();
builder.RegisterType<SubDependencyB>();
builder.RegisterType<DataInstallerA>().As<IDataInstaller>();
builder.RegisterType<DataInstallerA>().As<IDataInstaller>();
builder.RegisterType<DataService>();
Your DataService could then look like:
public class DataService
{
private IEnumerable<IDataInstaller> _dataInstallers;
public DataService(IEnumerable<IDataInstaller> dataInstallers) {
_dataInstallers = dataInstallers;
}
public void Install() {
foreach (var installer in _dataInstallers)
installer.InstallData();
}
}
The DataService isn't concerned with having to know how to create all of the IDataInstaller instances, AutoFac can do that, it just needs a collection of them.
Note that even though you didn't actually register the IEnumerable<IDataInstaller> AutoFac provides some extra registrations implicitly when you register a type. See http://autofac.readthedocs.org/en/latest/resolve/relationships.html.
While using Activator.CreateInstance(Type t) method you should make sure the type has parameterless consturctor available to type you are passing to its parametere otherwise it is gonna throw an exception that you got.
Why default consturctor is not there?
When you specify constructor with parameter in class default constructor is removed by compiler.
using System;
public class Program
{
public static void Main()
{
Test t = new Test() //will give you compile time error.
Test t1 = new Test(""); //should work fine.
}
}
public class Test
{
public Test(string a)
{
}
}
Use another overloaded method to pass constructor params there like below:
Activator.CreateInstance(typeof(T), param1, param2);
MSDN documentation for that method is here.
I am calling a method GetData from a class DataProvider, where the method is implemented as a interface. Calling is done as:
Response = ObjectRegistry.Instance.Resolve<IDataProvider>().GetData(id).
Structure of the interface looks like.
namespace A.B.C.D
{
///<Summary>
/// Gets the answer
///</Summary>
public interface IDataProvider
{
GetDataInfo GetData(int id);
}
}
and my DataProvider class looks like.
namespace A.B.C.D
{
public class DataProvider : IDataProvider
{
public GetDataInfo GetData(int id)
{
GetDataInfo DataInfo = new GetDataInfo();
//return obj;
return DataInfo;
}
}
}
But when I am trying to execute this I am getting following error:
Message: Resolution of the dependency failed, type = ".DataInfo.IDataProvider", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, DataInfo.IDataProvider, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:
Resolving DataInfo.IDataProvider,(none)
Tried searching in almost all the SO posts, but couldn't find any helpful suggestion
I have the following code implementation of my generic singleton provider:
public sealed class Singleton<T> where T : class, new()
{
Singleton()
{
}
public static T Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
static SingletonCreator()
{
}
internal static readonly T instance = new T();
}
}
This sample was taken from 2 articles and I merged the code to get me what I wanted:
http://www.yoda.arachsys.com/csharp/singleton.html and
http://www.codeproject.com/Articles/11111/Generic-Singleton-Provider.
This is how I tried to use the code above:
public class MyClass
{
public static IMyInterface Initialize()
{
if (Singleton<IMyInterface>.Instance == null // Error 1
{
Singleton<IMyInterface>.Instance = CreateEngineInstance(); // Error 2
Singleton<IMyInterface>.Instance.Initialize();
}
return Singleton<IMyInterface>.Instance;
}
}
And the interface:
public interface IMyInterface
{
}
The error at Error 1 is:
'MyProject.IMyInterace' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'MyProject.Singleton<T>'
The error at Error 2 is:
Property or indexer 'MyProject.Singleton<MyProject.IMyInterface>.Instance' cannot be assigned to -- it is read only
How can I fix this so that it is in line with the 2 articles mentioned above? Any other ideas or suggestions are appreciated.
Does my implementation break the Singleton pattern?
Basically, you've given a class constraint on your singleton class, along with the new() constraint.
When writing
Singleton<IMyInterface>
you're using an interface type as T, which violates the type constraint you defined.
For error 2,
Singleton<IMyInterface>.Instance = CreateEngineInstance();
you're trying to assign a value to a read-only property. So you need to define a setter on your Instance property for that line to work.
Update
Something along these lines should do it for you :
public sealed class Singleton
{
private static Hashtable bindings = new Hashtable();
private static Hashtable instances = new Hashtable();
private static void checkType(Type requested, Type bound)
{
if (requested.IsValueType)
throw new Exception("Cannot bind a value type to a reference type");
// also check type inheritance and other things...
}
private static void checkBinding(Type requested)
{
if (!(bindings.ContainsKey(requested)))
throw new Exception(String.Format("Type {0} was not bound !", requested.FullName));
}
public static void Bind<T, U>() where U : class, new()
{
checkType(typeof(T), typeof(U));
bindings[typeof(T)] = typeof(U);
}
public static T GetInstance<T>()
{
Type requested = typeof(T);
Type bound = (Type) bindings[requested];
checkBinding(requested);
if (!instances.ContainsKey(requested)) {
// We know that type "bound" was set with a new() class constraint
instances[requested] = (T) Activator.CreateInstance(bound);
}
return (T) instances[requested];
}
}
You could then write :
Singleton.Bind<IMyInterface, MyClass>();
IMyInterface instance = Singleton.GetInstance<IMyInterface>();
If you want to go further, you could also specify the lifecycle of the objects created by this provider, so that you could use singletons, or have the provider return a new object for each call, and so on.
You should also take a look at the Dependency Injection pattern, which seems close to what you want achieve, and also look at existing DI frameworks (NInject, Nhibernate) that already do this and much more.
Sure, you have an issue there. You generic is suppose to take class, not interface.
internal static readonly T instance = new T();
Your code suppose to create an instance of that class, you could not instantiate interface type.
So, if you need some type to act as singletone, you should write:
Singleton<MyInterface>.Instance
where
public class MyInterface : IMyInterface { }
Then you don't need to have any 'if' in you code, since it Singleton responsibility to instantite an object and keep it as only one instance.
Not related to question: currently Singletone's are considered by many developers as 'code-smell', so in general you have to avoid them. Try to think you application without Singletone at all.
I have this variable, it's an instance of a Interface of a class in business layer.
I need to send messages since data access layer, to business layer and finally to presentation layer. I my class "LogBinaryWriter" in data access I have this:
public class LogBinaryWriter : ILogBinaryWriter
{
private readonly IImageLogBuilder _imageLogBuilder;
public void WriteFrameCodes(string filePath, int logSelected)
{
var fileExists = FileExists(binaryFilePath);
if (fileExists == true)
{
_imageLogBuilder.displayMessage("The file " + binaryFileName + " exist. Dou you want overwrite it? (Y/N)");
}
}
}
I have a message: "the value _imageLogBuilder is never assigned and will always be null"
How can I fix this?
Instantiate an instance of IImageLogBuilder in your constructor for LogBinaryWriter and assign it to _imageLogBuilder. You would have to do it in the constructor since you have _imageLogBuilder marked as readonly.
For example, assuming you have a class called MyImageLogBuilder that implements IImageLogBuilder:
public LogBinaryWriter()
{
_imageLogBuilder = new MyImageLogBuilder();
}
You could also overload the constructor so you can pass in the IImageLogBuilder you want to use (lookup constructor injection for more info on this pattern):
public LogBinaryWriter(IImageLogBuilder imageLogBuilder)
{
_imageLogBuilder = imageLogBuilder;
}
Remember, you will need a class that implements the IImageLogBuilder interface to be able to create a new instance and assign it to the _imageLogBuilder variable. For example:
public interface IImageLogBuilder
{
void Log(string message);
}
//The class below IMPLEMENTS the IImageLogBuilder interface
public class MyImageLogBuilder : IImageLogBuilder
{
//Implement IImageLogBuilder methods here
public void Log(string message)
{
//Log message
}
}
If you had something like the classes defined above then you could the following in the LogBinaryWriter constructor and you would no longer get the null reference error.
public LogBinaryWriter()
{
_imageLogBuilder = new MyImageLogBuilder();
}
You need to assign an instance of a class that implements IImageLogBuilder interface to _imageLogBuilder field.
Right now your field will always have a value of null.
For example:
private readonly IImageLogBuilder _imageLogBuilder = new ImageLogBuilder();
perhaps initialize _imageLogBuilder in constructor ?
public class LogBinaryWriter : ILogBinaryWriter
{
private readonly IImageLogBuilder _imageLogBuilder;
public LogBinaryWriter(IImageLogBuilder imageLogBuilder)
{
_imageLogBuilder = imageLogBuilder;
}
....
}
You never set the value of the _imageLogBuilder variable. And since you marked it as readonly, the only place it can be set is in a field initializer, or in a constructor.
Did you mean to do something like this, perhaps?
private readonly IImageLogBuilder _imageLogBuilder = // get the value from somewhere else, or make a new one