Using Dependency Injection for classes instantiated at run time - c#

I have two classes: ImportBase.cs (Parent) and ImportFleet.cs (Child) which will in the future import a CSV file. Each child of ImportBase will implement a different implementation of the actual import code.
The approriate child class to use is determined in a Service class where the correct class is instantiated and the import method called. All is going well up until this point.
The problem is that I also want to Dependency Inject some repository classes into ImportBase and it's inherited classes (as I have attempted in the code below):
ImportBase.cs
namespace WebApi.Services.Import.Investments
{
interface IImport
{
public void Import(IFormFile file, int UserId);
}
public abstract class ImportBase : IImport
{
public abstract void Import(IFormFile file, int UserId);
protected List<InvestmentTransactionType> transactionTypes = new();
protected IInvestmentEntityRepository _investmentEntityRepository;
public ImportBase(IInvestmentEntityRepository investmentEntityRepository)
{
_investmentEntityRepository = investmentEntityRepository;
}
}
}
ImportFleet.cs
namespace WebApi.Services.Import.Investments
{
public class ImportFleet : ImportBase
{
public ImportFleet(IInvestmentEntityRepository investmentEntityRepository) : base(investmentEntityRepository)
{
}
public override void Import(IFormFile file, int UserId)
{
}
}
}
InvestmentService.cs
namespace WebApi.Services
{
public interface IInvestmentService
{
public void Import(IFormFile file, int UserId, int InvestmentEntityId);
}
public class InvestmentService: IInvestmentService
{
public void Import(IFormFile file, int UserId, int InvestmentEntityId)
{
IImport importService = null;
string investmentEntity = ImportBase.determineInvestmentEntityFromCsv(file);
switch(investmentEntity)
{
case "fleet":
importService = new ImportFleet(); // problem is here
break;
}
if (importService != null)
{
importService.Import(file, UserId);
}
}
}
}
The problem is the following line:
importService = new ImportKuflink();
Because I only determine which child class to instantiate at run time, I cannot take advantage of DI here.
Under normal circumstances I would make the Import classes a DI based service so all dependencies are available, however I have to create the instance at run time so this I don't think is possible.
Is there a way to accomplish the above?

Here's a simplified version of your code that demonstrates how you can populate an instance of an object from a DI service container.
In your InvestmentService:
Inject the IServiceProvider.
Use the little known utility ActivatorUtilities to get a fully DI'd instance of your object.
Make sure you dispose it properly if it implemenents IDisposable. I've included an async version if you use anything that needs a IAsyncDisposable.
public class InvestmentService : IInvestmentService
{
private IServiceProvider _serviceProvider;
public InvestmentService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
//...
}
public Import()
{
IImport? importService = null;
IDisposable? disposable = null;
var importFleet = ActivatorUtilities.CreateInstance<ImportFleet>(_serviceProvider);
if (importFleet is IDisposable)
disposable = importFleet as IDisposable;
importService = importFleet as IImport;
// Do whatever you want to do with it
disposable?.Dispose();
}
public async ValueTask ImportAsync()
{
IImport? importService = null;
IDisposable? disposable = null;
IAsyncDisposable? asyncDisposable = null;
var importFleet = ActivatorUtilities.CreateInstance<ImportFleet>(_serviceProvider);
if (importFleet is IDisposable)
disposable = importFleet as IDisposable;
if (importFleet is IAsyncDisposable)
asyncDisposable = importFleet as IAsyncDisposable;
importService = importFleet as IImport;
// Do whatever you want to do with it
disposable?.Dispose();
if (asyncDisposable is not null)
await asyncDisposable.DisposeAsync();
}
}

Yes, of course there is a way to accomplish this. But I guess the DI container you are using (like from MS) won't help you here.
I've been fiddling with crap like this for like two years so far and still am busy with it. Two years of creating my own IoC framework.
Usual DI/IoC microkernels follow OCP and other really mandatory concepts and patterns. What I've done is leaving one single small door open. I won't bore you with details. The fundamental idea is that a class must be decorated with the appropriate attributes in code, and then is able to call the microkernel within its constructor (which has been called by a simple "var foo = new Barney();") to let an entity be modified like it had been created by the microkernel.
There is no(t yet a) way to hook into the plain new() code. Some cheer this, some don't. I'm with the cheerleaders here. Why? Side-effects.
Imagine this:
public class SomeNumber
{
public int SomeValue { get; private set; }
public SomeNumber()
{
SomeValue = 19;
}
}
Okay? Let's assume you'd modified the new() process by whatever, then another user of your code goes:
Assert.AreEqual(19, someNumberEntity.SomeNumber);
and this code throws an exception, because for whatever reason your modifying code set the number to 7.
Now look at this code (from a unit test):
using System.Reflection;
using Kis.Core.Attributes;
namespace UnitTests_Kis.Core
{
[KisAware]
public class KisAwareSimpleClass
{
[Property(value: 123)]
public int ValueToCheck { get; set; } = 0;
[Property(value: "I am the doctor!")]
public string Name { get; set; } = "";
public KisAwareSimpleClass()
{
var t = this.GetType();
var fqtn = t.FullName;
var ec = new Kis.Core.EntityCreator(Assembly.GetAssembly(t));
ec.ModifyExistingEntity(fullyQualifiedTypeName: fqtn, existingEntity: this);
}
}
}
Clean code isn't always easily readable, but the aspects/attributes will raise coder's awareness.
PS: I posted the unit test code on purpose to show you what's happening.
Short version:
Microkernel.Modify(this);

You can inject a factory which has the services injected into it.
public interface IImportFactory
{
ImportFleet CreateFleetImporter();
}
public class MyImportFactory : IImportFactory
{
private readonly IMyDependency1 _dependency1;
private readonly IMyDependency2 _dependency2;
public MyImportFactory(IMyDependency1 dependency1, IMyDependency2 dependency2)
{
_dependency1 = dependency1;
_dependency2 = dependency2;
}
public ImportFleet CreateFleetImporter()
{
return new ImportFleet(_dependency1, _dependency2);
}
}
Then inject the factory as a dependency in your Service class.

Related

Resolving concrete types when using polymorphism in Autofac

Consider the following code:
public interface IFileBackup
{
Task Backup(byte[] file);
}
public class BackUpMechanismA : IFileBackup
{
//Implementation
public async Task Backup(byte[] file)
{
//Attempts to backup using mechanism A
}
}
public class BackUpMechanismB : IFileBackup
{
//Implementation
public async Task Backup(byte[] file)
{
//Attempts to backup using mechanism B
}
}
Then the calling class looks like this:
public class Caller
{
private readonly IFileBackup _backupA;
private readonly IFileBackup _backupB;
public Caller(IFileBackup backupA, IFileBackup backupB)
{
_backupA = backupA;
_backupB = backupB;
}
public async Task BackupFile(byte[] file)
{
try
{
await _backupA.Backup(file);
}
catch(SomeException)
{
await _backupB.Backup(file);
}
}
}
So what I'm trying to do here is to use polymorphism. So both BackupMechanismA and BackupMechanismB implements the Backup method in their own way. In the caller I want to attempt the first mechanism and if that doesn't work we catch an exception and try the second approach.
I'm having trouble resolving the correct implementations using Autofac. I have tried with:
builder.RegisterType<BackupMechanismA>().As<IFileBackup>().AsSelf();
builder.RegisterType<BackupMechanismB>().As<IFileBackUp>().AsSelf();
But this won't work because I still need to tell the caller which of the types to resolve. How do I do that in the caller?
Also, I'm in doubt whether this design is really the right design to go with. Before this design I just had one class with two different methods, one for mechanism A and one for mechanism B and then the caller would just call the different methods in the try catch. So I wanted to refactor this because the class got quite big and I wanted to separate the two different mechanisms into their own classes.
So, can I resolve this using Autofac? And is it the right design to go with for this scenario?
Agree with Jogge that iterating IFileBackups would be a better option, but creating an interface for each type is a no go. Instead, you could add a class which provides IEnumerable<IFileBackup> (an aggregate). For example:
public class BackupBundle : IEnumerable<IFileBackup>
{
private readonly List<IFileBackup> _backups = new List<IFileBackup>();
// default constructor creates default implementations
public BackupBundle()
: this(new List<IFileBackup> {new BackUpMechanismA(), new BackUpMechanismB()}) {}
// allow users to add custom backups
public BackupBundle(IEnumerable<IFileBackup> backups)
{
foreach (var backup in backups)
Add(backup);
}
public void Add(IFileBackup backup)
{
if (backup == null) throw new ArgumentNullException(nameof(backup));
_backups.Add(backup);
}
public IEnumerator<IFileBackup> GetEnumerator()
{
foreach (var backup in _backups)
yield return backup;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Caller
{
private readonly IEnumerable<IFileBackup> _backups;
public Caller(IEnumerable<IFileBackup> backups)
{
_backups = backups ?? throw new ArgumentNullException(nameof(backups));
}
public async Task BackupFile(byte[] file)
{
foreach (var b in _backups)
{
try
{
await b.Backup(file);
break;
}
catch (Exception e) { }
}
}
}
Registration can be done as follows:
builder.RegisterInstance(new BackupBundle()).As<IEnumerable<IFileBackup>>();
builder.RegisterType<Caller>();
which allows you to resolve by class name:
var caller = scope.Resolve<Caller>();
As you see, the BackupBundle has a dependency of BackUpMechanismA and BackUpMechanismB. You could get rid of it by introducing another layer of abstraction but I'd prefer not to do that. My main concern would be to make Caller more robust. You might want to introduce retry logic, timeouts, etc.
Try registering with a name and then resolve using the name:
builder.RegisterType<BackupMechanismA>().Named<IFileBackup>("BackUpMechanismA");
builder.RegisterType<BackupMechanismB>().Named<IFileBackUp>("BackUpMechanismB");
_backupA = container.ResolveNamed<IFileBackUp>
("BackUpMechanismA");
_backupB = container.ResolveNamed<IFileBackUp>
("BackUpMechanismB");
Resolve the instances during runtime, rather than injecting through the constructor. This will let you resolve to the respective type, as needed.
Let me know if this works.
To make your design work, you can try the next approach:
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterType<BackUpMechanismA>().Keyed<IFileBackup>("A");
builder.RegisterType<BackUpMechanismB>().Keyed<IFileBackup>("B");
builder.RegisterType<Caller>()
.WithParameter((p, ctx) => p.Position == 0, (p, ctx) => ctx.ResolveKeyed<IFileBackup>("A"))
.WithParameter((p, ctx) => p.Position == 1, (p, ctx) => ctx.ResolveKeyed<IFileBackup>("B"));
IContainer container = builder.Build();
var caller = container.Resolve<Caller>();
Console.ReadKey();
}
However in my opinion you probably don't need such a polymorphism here. It will be much more obvious and descriptive to implement something like this:
public async Task BackupFile(byte[] file)
{
try
{
await BackUpToAmazonS3(file);
}
catch (AmazonS3LoadingException)
{
await BackUpToLocalDisk(file);
}
}
In this example it is obvious what is going on. And there in BackUpToAmazonS3 you can use some injected AmazonS3FileBackUp and in BackUpToLocalDisk use LocalDiskFileBackUp or whatever. The point is that you don't need a polymorphism, when you don't plan to change the implementation. In your context it should be clear? that you try to put backup to some remote storage, and then, if it fails, put in on local disk. You don't need to hide the meaning here. This is your logic and should be clear, when you read the code, I suppose. Hope it helps.
In my experience, you're better off by creating an interface for each type:
public interface IFileBackup
{
Task Backup(byte[] file);
}
public interface IBackUpMechanismA : IFileBackup
{
}
public class BackUpMechanismA : IBackUpMechanismA
{
//...
}
public interface IBackUpMechanismB : IFileBackup
{
}
public class BackUpMechanismB : IBackUpMechanismB
{
//...
}
If you don't want that, what you could do is getting injected a list of IFileBackup and just iterate them. If you register BackUpMechanismA first it will be the first in the list. I'm not sure if this is guaranteed, you have to look it up.
public class Caller
{
private readonly ICollection<IFileBackup> _fileBackups;
public Caller(ICollection<IFileBackup> fileBackups)
{
_fileBackups = fileBackups;
}
public async Task BackupFile(byte[] file)
{
foreach (var fileBackup in _fileBackups)
{
try
{
await fileBackup.Backup(file);
break;
}
catch { }
}
}
}

How to share the same context between commands in Command-Pattern with C#?

I've implemented the command pattern (in a multi-support way) in my application.
Structure:
class MultiCommand : BaseCommand
abstract class BaseCommand : ICommand
Process Flow:
var commandsGroup = new MultiCommand(new List<ICommand>()
{
new Command1(),
new Command2(),
new Command3(),
});
commandsGroup.Execute()
Now, suppose that in Command1 a somethingID is changed and I'll use this new value in Command2... And also, that there are plenty of other properties and objects that are being affected during the whole execution process.
Also, there are some interface implementations that should be available at any command just using the context object like:
Context.ServerController.something();
The instantiation of the IServerController will take place just before the multiCommandGroup initialization.
How can I have a shared context like this for all Commands of the group?
Example of the Context class:
public class CommandContext
{
public IServerController ServerController;
public RequiredData Data { get; set; }
public CommandContext(){}
}
IMPORTANT
A minimal implementation Code is here
1) If you want to keep this interface, then you have to pass this context as constructor parameter:
new MultiCommand(new List<ICommand>()
{
new Command1(context),
new Command2(context),
new Command3(context),
})
2) As another option you can accept list of delegates instead of list of commands.
MultiCommand will be look like this:
class MultiCommand : ICommand
{
public MultiCommand(List<Func<Context, Command>> commands, Context context)
}
That is almost the same except MultiCommand is responsible for all the commands share the same context.
3) Looks like commands in MultiCommand depends on result of previous command. In this case Command pattern is not probably the best. Maybe you should try to implement Middleware chain here?
interface IMiddleware<TContext>
{
void Run(TContext context);
}
class Chain<TContext>
{
private List<IMiddleware<TContext>> handlers;
void Register(IMiddleware<TContext> m);
public void Run(TContext context)
{
handlers.ForEach(h => h.Run(context));
}
}
I would suggest to make somethings generic. Here is a super simple example.
class MultiCommand<TContext>
{
List<Command<TContext>> Commands;
TContext Context;
}
You could have a constructor on your BaseCommand class (and its derived classes) that would accept a Context class of some kind. When instantiating the commands that will belong to the same group, you could provide them all the same context object. Maybe something like:
public class CommandContext
{
// The object that will be the target of the commands' actions.
public object Data { get; set; }
// ... any other properties that might be useful as shared state between commands...
}
public abstract class BaseCommand : ICommand
{
protected CommandContext Context { get; private set; }
public BaseCommand(CommandContext ctx)
{
Context = ctx;
}
}
public class ChangeSomethingIDCommand : BaseCommand
{
public ChangeSomethingIDCommand(CommandContext ctx) : base(ctx)
{ }
public void Execute()
{
var target = (SomeDomainClass)Context.Data;
target.SomethingID++;
}
}
// Elsewhere in your code (assuming 'myTargetDomainClassInstance' is
// a SomeDomainClass instance that has been instantiated elsewhere and
// represents the object upon which the commands will do work):
var ctx = new CommandContext { Data = myTargetDomainClassInstance };
var commandGroup = new MultiItemCommand(ctx, new List<ICommand>
{
new ChangeSomethingIDCommand(ctx),
new Command2(ctx),
new Command3(ctx)
});
commandGroup.Execute();
Consider a Functional Style
public class SomeMainClass{
public void MultiCommandInit()
{
MultiCommand.New()
.Add(new Command1())
.Add(new Command2())
.Add(new Command3())
.SharedContext(CC => {
CC.Data = new RequiredData();
CC.ServerController = GetServerController();
});
}
private IServerController GetServerController()
{
// return proper instance of server controller
throw new NotImplementedException();
}
}
Requires this extension method / function...
public static class XMultiCommand
{
// How can I have a shared context like this for all Commands of the group?
public static MultiCommand SharedContext(this MultiCommand mc, Action<CommandContext> CallBack)
{
var cc = new CommandContext();
CallBack(cc);
mc.SharedContext = cc;
return mc;
}
}
Finally, these changes to MultiCommand
public class MultiCommand
{
private System.Collections.Generic.List<ICommand> list;
public List<ICommand> Commands { get { return list; } }
public CommandContext SharedContext { get; set; }
public MultiCommand() { }
public MultiCommand(System.Collections.Generic.List<ICommand> list)
{
this.list = list;
}
public MultiCommand Add(ICommand cc)
{
list.Add(cc);
return this;
}
internal void Execute()
{
throw new NotImplementedException();
}
public static MultiCommand New()
{
return new MultiCommand();
}
}
Cool Things Happen Using Functional Styles
Re-usability soars!
Hyper focus on Single Responsibility concerns
Composition becomes the Norm
Code Maintenance becomes simple
Intellisense becomes your built-in API (just use code commenting)
No radical OOP design patterns are needed
Fluent code becomes very enjoyable to work with
Nested / Decorated Functions are much more easy to imagine and implement
You will never repeat youerself
The Open/Closed principal becomes your religion
Code is now always Clear, Complete and Concise
Some even say no interfaces are needed any longer
In your case, going with injecting context through constructor is fine as mentioned by others. But in general, I would go with injecting the context through method parameters instead:
public class Command1: BaseCommand
{
//inject as parameter instead
public void Execute(Context ctx)
{
}
}
The reasons are:
The context should be managed by CommandGroup so that we have better encapsulation.
The CommandGroup is responsible for executing its list of commands so that it's possible for the CommandGroup to pass to each Command only the parameters each Command really needs, these parameters may be constructed at runtime (maybe by previous Commands) so that it's not possible to pass in these objects as the time we construct the list of commands. Therefore, it's easier to reuse Command and also simplify unit testing these Commands as we don't need to construct the whole context object in unit tests.
Maybe you don't need to care about these things at the moment, but method injection gives more flexibility. If you have worked with some frameworks in .NET, you would see something similar like OwinContext, FilterContext,.. they are passed as parameters and contain relevant information for that context.
In my opinion, your case is not a good fit for Command pattern. A Command represents a user request (action) and these objects could be created dynamically at runtime, but you're predefining your Commands at coding time.
What you're trying to do looks like owin middleware or asp.net web api message handler which are http://www.dofactory.com/net/chain-of-responsibility-design-pattern
And what about changing your approach? I did an architecture for DDD recently and executing a commad implies atomic operation (retrieve aggregate root from persitence, apply domain rules and pesist the aggregate) so I do not in needed of a share context and can batch multiple commands whithout worries.
Here you have an cqrs architecture that use command pattern with the above strategy I posted.
My 0.02:
1) The MultiCommand class looks like a Composite pattern.
You may want to add a GetParentCommand() method at the base command class and add an AddChildCommand() method at the MultiCommand class, which set every children's parent.
Then the children commands could get the context object from its parent. (Context object should also be defined in base class. And it may be of generic type.)
edit:
abstract class BaseCommand<T> : ICommand
{
public T Context { get; set; }
public BaseCommand Parent { get; set; }
}
class MultiCommand : BaseCommand
{
public void AddChildCommand(BaseCommand command)
{
command.parent = this; // we can get parent's context from children now
// put the command in an internal list
}
}
var commandsGroup = new MultiCommand();
commandsGroup.AddChildCommand(new Command1());
commandsGroup.AddChildCommand(new Command2());
commandsGroup.AddChildCommand(new Command3());
commandsGroup.Execute()
2) We may create a global singleton context object. In MultiCommand's Execute function, we could set the current context object before executing children's Execute function. Then child command could just access the singleton context object. And after all children's execution, the MultiCommand could reset the context. (The context is actually a stack here.)
edit:
abstract class BaseCommand : ICommand
{
// it could be put anywhere else as long as it can be accessed in command's Execute
// it can also be a stack
public static CommandContext Context {get; set;}
}
class MutliCommand : BaseCommand
{
public void Execute()
{
// do something to BaseCommand.Context
ChildCommand.Execute();
// do something to BaseCommand.Context
}
}
class ChildComand: BaseCommand
{
void Execute()
{
// do something with BaseCommand.Context
}
}
Another option is to put the context object as a parameter of the Execute function:
class MultiCommand : BaseCommand
{
void Execute(CommandContext context)
{
Children.Execute(context);
}
}

Creating and initialize a class inside another class (nested) C#

I'm very new in C# and i need some help to use nested classes on my "Hello World" proyect.
I'm trying to create a class callable using class1.subclass1.function(args...) (to create groups of related functions), and I've done something that is working but I think that is not the best way to do it.
My code needs to share a variable between principal class and nested classes (a db handle), and I'm using and argument at class initialization to do it.
namespace SameAsPrincipal
{
public class class1
{
public SQLiteConnection handle = null;
public _subclass1 subclass = null;
public class1(string db_file)
{
handle = new SQLiteConnection(db_file);
subclass1 = new _subclass1(handle);
}
public _subclass1
{
private SQLiteConnection handle = null;
public _subclass1(SQLiteConnection handle)
{
this.handle = handle;
}
public void function(args...)
{
//Do something here
}
}
}
}
Someone knows a better way to create nested classes and share objects between main and nested?
Thanks!!
I am unclear as to why you would want to use a nested class in this instance. The way you have it written, the subclass is all you need. If you want multiple methods (or as you called them "functions") just add your methods.
Is there some hidden reason you would want to use nested classes here? As a general rule, nested classes are rarely needed.
namespace SameAsPrincipal
{
public class Class1
{
private SQLiteConnection handle;
public Class1(string db_file)
{
handle = new SQLiteConnection(db_file);
}
public int AddRecord(Record record)
{
// use handle to add record and get record Id
return record.Id;
}
public void DeleteRecord(int id)
{
// Use handle to delete record
}
}
}
When you instantiate the object you will pass in your db_file and the connection object will be created. Then every method could use that connection object when they are called. However it is usually a better idea to create the connection for each method when it is called and disposing of the connection as soon as you the operation is completed. This, of course, depends on your operations and if they are transnational. For the most part using a "using" block to instantiate your connection is a good way to use connection objects. The sooner you release the connection the sooner the machine will reuse that connection, you can lookup connection pooling to learn more.
Here is an example method that is using the "using" to add a person using a stored procedure:
public int AddPerson(Person person)
{
using (var connection = new SQLiteConnection(dbFile))
{
connection.Open();
using (var command = new SQLiteCommand("spAddPerson",connection))
{
command.CommandType = CommandType.StoredProcedure;
var idParameter = new SQLiteParameter("#Id", DbType.Int32);
idParameter.Direction = ParameterDirection.Output;
command.Parameters.Add(idParameter);
command.Parameters.AddWithValue("#FirstName", person.FirstName);
command.Parameters.AddWithValue("#LirstName", person.LastName);
command.ExecuteNonQuery();
}
}
return person.Id;
}
edit: In regard to your comment below
A few things:
Use namespaces not a parent class to group classes.
Instead of sub-classes you should just add all the database methods to the database class and create classes to model your objects.
Each class should be in it's own file
The namespace parts are ..[]* I.E. Music class has the namespace YourApplication.YourProject.Models - inside the YourProject project, within a first level folder named Music you will find a file named Music.cs and with in that file you will find your music class. This is not a requirement, the compiler does not care about structure like that. It will only make your life easier when you start to get more code developed.
Here is an example of the code structure I am speaking of (remember each of these sections is it's own file)
Create a folder at the root of your project called Models. In this Models folder create a file named Music.cs
namespace YourApplication.YourProject.Models
{
public class Music
{
public int Id { get; set; }
public string Title { get; set; }
public double Length { get; set; }
public string Artist { get; set; }
public string Album { get; set; }
}
}
In this same (Models) folder create a file called Film.cs
namespace YourApplication.YourProject.Models
{
public class Film
{
public int Id { get; set; }
public string Title { get; set; }
public double Length { get; set; }
public string Director { get; set; }
public string[] Actors { get; set; }
}
}
Now back at the project root (no longer in Models folder) create a new folder called Persistence.
using System;
using System.Collections.Generic;
using System.Data.SQLite;
using YourApplication.YourProject.Models;
namespace YourApplication.YourProject.Persistence
{
public static class DatabaseActions
{
public static string dbFile;
public static Music[] ListMusic()
{
var musicList = new List<Music>();
// database call to get all music
using (var connection = new SQLiteConnection(dbFile))
{
connection.Open();
using (var command = new SQLiteCommand("spGetMusic", connection))
{
var reader = command.ExecuteReader();
// The try finally blocks are not strictly needed as these will are suppose to be called upon disposal
try
{
// loop through records creating music objects
while (reader.Read())
{
var music = new Music();
music.Id = reader.GetInt32(0);
music.Title = reader.GetString(1);
musicList.Add(music);
}
}
finally
{
reader.Close();
connection.Close();
}
}
}
return musicList.ToArray();
}
public static int SaveMusic(Music music)
{
if (music.Id == 0)
{
// database stuff - getting the newly created database id
}
else
{
// database calls to update record
}
return music.Id;
}
public static int SaveFilm(Film film)
{
if (film.Id == 0)
{
// database stuff - getting the newly created database id
}
else
{
// database calls to update record
}
return film.Id;
}
public static Music GetMusic(int id)
{
var music = new Music();
// database call and setting of values on music
return music;
}
public static Film GetFilm(int id)
{
var film = new Film();
// database call and setting of values on music
return film;
}
}
}
Now finally create a file on the root called WorkHarness.cs
using System;
using YourApplication.YourProject.Persistence;
namespace YourApplication.YourProject
{
public class WorkHarness
{
public void Initialize()
{
DatabaseActions.dbFile = "your db file";
}
public void ShowMusicList()
{
// list the id and title so user can select by Id
foreach (var music in DatabaseActions.ListMusic())
{
Console.WriteLine("{0,-10}{1}",music.Id,music.Title);
}
}
public void DisplayMusicItem(int id)
{
var music = DatabaseActions.GetMusic(id);
Console.WriteLine("Title: " + music.Title);
Console.WriteLine("Length: " + music.Length);
Console.WriteLine("Artist: " + music.Artist);
Console.WriteLine("Album: " + music.Album);
}
}
}
Without more context as to what the specific application is, it's hard to tell if it's appropriate or not. I agree with the previous answer that it is generally more correct to have separate classes. Your class B can still take a DB handle reference in its constructor, and class A can even pass it to it. That's fine. It's not so much that they are sharing the variable as that they both have a reference to the same DB handle.
The only time I've ever seen sub/inner classes and not thought it was weird was for like simple data objects that are only ever used within the parent class (although they may be referenced outside). For example, if I made a linked list class, I may choose to have the node class be an inner class. For just grouping functionality, regular classes should do that.
Namespaces can also be used for further grouping. For example, maybe all my text operations are in a "MyApp.Text" namespace, but then they are further grouped into classes like "NumberUtils", "NameUtils", and "ZipUtils".
Instead of nesting the objects, create two classes (at the same scope) and have one use the other, such as this:
public class ClassA
{
public ClassB InstanceOfClassB { get; set; }
public ClassA()
{
InstanceOfClassB = new ClassB();
}
//More code here
}
public class ClassB
{
//Code here
}
Using Nested classes in a HelloWorld project? Not a good sign!!
I would suggest not to use nested types Unless you know what you're doing and you have very good explanation to give when asked. Also a note of advice by .NET Framework Guidelines which explicitly recommend against creating public nested classes.
For data sharing in Object oriented programming we have inheritance feature which is the best way to share data/members access across classes based on relationship/association.
to create groups of related functions
As #Nex Terren suggested (with a little modification), you can do something like this, here your Principle class will work as Factory and different classes will provide Aggregation of related functions by their instance
public class PrincipleClass
{
public ClassB InstanceOfClassB { get; private set; }
public ClassA InstanceOfClassA { get; private set; }
public PrincipleClass(string db_file)
{
InstanceOfClassA = new ClassA(new SQLiteConnection(db_file));
InstanceOfClassB = new ClassB();
}
//More code here
}
public class ClassA
{
public ClassA(SQLiteConnection handle)
{
// your code here
}
public void FunctionOfA1() { }
public void FunctionOfA2() { }
}
public class ClassB
{
public void FunctionOfB1() { }
public void FunctionOfB2() { }
}
Now you'll have your group of function together like
new PrincipleClass.InstanceOfClassA.FunctionOfA1();
new PrincipleClass.InstanceOfClassB.FunctionOfB1();
Note - This may also not be a best solution but this is way better than using Nested types.

How to remove(unregister) registered instance from Unity mapping?

I meet one problem that i can't solve now.
I have the following:
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance);
where UnityHelper.DefaultContainer is my helper for getting unity container with loaded configuration.
here I registered instance as an instance of IMyInterface.
So anywhere( some time after using) I want to remove this mapping. Remove it at all. How I can do it?
I have tried:
UnityHelper.DefaultContainer.Teardown(instance)
but is was unsuccessful and the following code returns instance anyway:
UnityHelper.DefaultContainer.ResolveAll<IMyInterface>()
I had the same problem and just removed the registrations of the ContainerControlledLifetimeManager from my Container:
foreach (var registration in container.Registrations
.Where(p => p.RegisteredType == typeof(object)
&& p.Name == name
&& p.LifetimeManager.Type == typeof(ContainerControlledLifetimeManager)))
{
registration.LifetimeManager.RemoveValue();
}
This is an old question, but some answers are misleading, so I will provide my own.
You can´t do that with Unity. End of the story.
Calling RemoveValue on registrations lifetime managers does not achieve unregistration (more information about lifetime managers), and that method is not intended to unregister anything. So the final behaviour is unexpected and not convenient. Of course, RemoveValue makes even less sense if you register an implementation or a factory method, although the question is about unregistering instances.
Consider the next piece of code
public interface SomeInterface
{
int Foo { get; set; }
}
public class SomeImplementation: SomeInterface
{
public int Foo { get; set; }
}
static void Main(string[] args)
{
UnityContainer iocContainer = new UnityContainer();
string registerName = "instance";
//before any registration
Resolve<SomeInterface>(iocContainer, registerName);
iocContainer.RegisterInstance<SomeInterface>(registerName, new SomeImplementation());
//after registration
Resolve<SomeInterface>(iocContainer, registerName);
ClearValue<SomeInterface>(iocContainer, registerName);
//after clear value
Resolve<SomeInterface>(iocContainer, registerName);
}
private static void Resolve<T>(UnityContainer iocContainer,string name)
{
if (iocContainer.IsRegistered<T>(name))
iocContainer.Resolve<T>(name);
iocContainer.ResolveAll<T>();
}
private static void ClearValue<T>(UnityContainer iocContainer, string name)
{
foreach (var registration in iocContainer.Registrations.Where(p => p.RegisteredType == typeof(T)
&& p.Name==name))
{
registration.LifetimeManager.RemoveValue();
}
}
If you debug it, you will see that after the call to ClearValue, the container still says it is registered, but if you try to resolve that instance it will throw an exception. What is even worse, calls to ResolveAll<T> will fail too.
To Sum up, no matter if you do ClearValue, wrap around your register instance with another IoC or a custom class, or provide your own LifeTimeManager, ResolveAll<T> and IsRegistered<T> won´t behave as expected, and the registration will still be there. So don't try it because it won´t work and it will cause problems down the road.
I think that is what you are looking for.
var lifetimeManager = new TransientLifetimeManager();
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance, lifetimeManager);
lifetimeManager.RemoveValue();
Here is how I handled unregistering instances from a unity container
I needed to implement Add/Remove functionality like this:
public interface IObjectBuilder
{
void AddInstance<T>(T instance);
void RemoveInstance<T>(T instance);
}
I created a custom lifetime manager to do the implementation
public class ExplicitLifetimeManager :
LifetimeManager
{
object Value;
public override object GetValue()
{
return Value;
}
public override void SetValue(object newValue)
{
Value = newValue;
}
public override void RemoveValue()
{
Value = null;
}
}
Here is the final implementation:
Dictionary<object, ExplicitLifetimeManager> Instances = new Dictionary<object, ExplicitLifetimeManager>();
public void AddInstance<T>(T instance)
{
ExplicitLifetimeManager e = new ExplicitLifetimeManager();
Instances[instance] = e;
Container.RegisterInstance(instance, e);
}
public void RemoveInstance<T>(T instance)
{
Instances[instance].RemoveValue();
Instances.Remove(instance);
}
calling removevalue on the custom lifetime manager causes the instance to be unregistered
I have the same challenge and after experimenting I solved it by using the standard ContainerControlledLifetimeManager and calling RemoveValue when I want to remove the container instance. Note that if you are not using interfaces and your object has constructor which the container can find and use it will recreate the instance after you have destroyed it with lifetimeManager.RemoveValue().
[TestClass]
public class UnityContainerTest
{
[TestMethod]
public void RemoveFromContainer()
{
UnityContainer container = new UnityContainer();
MyUnityMember member = new MyUnityMember(5);
LifetimeManager lifetimeManager = new ContainerControlledLifetimeManager();
container.RegisterInstance(member, lifetimeManager);
var resolved = container.Resolve<MyUnityMember>();
Assert.IsNotNull(resolved);
lifetimeManager.RemoveValue();
try
{
resolved = container.Resolve<MyUnityMember>();
Assert.Fail(resolved + " is still in the container");
}
catch (ResolutionFailedException)
{
}
}
public class MyUnityMember
{
public MyUnityMember(int x)
{
I = x;
}
public int I { get; private set; }
}
}
I had a similar requirement whereby I wanted to temporarily store objects in the unity container and found this was not possible (or at least easily possible).
If your objective is to have a temporary storage place easily available to unity, then create a temporary storage service.
public class TemporaryStorageService : ITemporaryStorageService
{
public void Deposit<T>(Object o, string key)
{
System.Windows.Application.Current.Properties[key] = o;
}
public T Withdraw<T>(string key)
{ T o = (T)System.Windows.Application.Current.Properties[key];
System.Windows.Application.Current.Properties.Remove(key);
return o;
}
}
Register your service with Unity. Then when you wish to store an object you call the Deposit Method and when you wish to remove the object you call the Withdraw method.
A fuller explanation can be found here

Fake ASMX Web Service Call

I built a .NET ASMX web service connecting to an SQL Server database. There is a web service call GetAllQuestions().
var myService = new SATService();
var serviceQuestions = myService.GetAllQuestions();
I saved the result of GetAllQuestions to GetAllQuestions.xml in the local application folder
Is there any way to fake the web service call and use the local xml result?
I just want to take the contents of my entire sql table and have the array of objects with correlating property names automatically generated for me just like with LINQ to SQL web services.
Please keep in mind that I am building a standalone Monotouch iPhone application.
Use dependency injection.
//GetSATService returns the fake service during testing
var myService = GetSATService();
var serviceQuestions = myService.GetAllQuestions();
Or, preferably, in the constructor for the object set the SATService field (so the constructor requires the SATService to be set. If you do this, it will be easier to test.
Edit: Sorry, I'll elaborate here. What you have in your code above is a coupled dependency, where your code creates the object it is using. Dependency injection or the Inversion of Control(IOC) pattern, would have you uncouple that dependency. (Or simply, don't call "new" - let something else do that - something you can control outside the consumer.)
There are several ways to do this, and they are shown in the code below (comments explain):
class Program
{
static void Main(string[] args)
{
//ACTUAL usage
//Setting up the interface injection
IInjectableFactory.StaticInjectable = new ConcreteInjectable(1);
//Injecting via the constructor
EverythingsInjected injected =
new EverythingsInjected(new ConcreteInjectable(100));
//Injecting via the property
injected.PropertyInjected = new ConcreteInjectable(1000);
//using the injected items
injected.PrintInjectables();
Console.WriteLine();
//FOR TESTING (normally done in a unit testing framework)
IInjectableFactory.StaticInjectable = new TestInjectable();
EverythingsInjected testInjected =
new EverythingsInjected(new TestInjectable());
testInjected.PropertyInjected = new TestInjectable();
//this would be an assert of some kind
testInjected.PrintInjectables();
Console.Read();
}
//the inteface you want to represent the decoupled class
public interface IInjectable { void DoSomething(string myStr); }
//the "real" injectable
public class ConcreteInjectable : IInjectable
{
private int _myId;
public ConcreteInjectable(int myId) { _myId = myId; }
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", _myId, myStr);
}
}
//the place to get the IInjectable (not in consuming class)
public static class IInjectableFactory
{
public static IInjectable StaticInjectable { get; set; }
}
//the consuming class - with three types of injection used
public class EverythingsInjected
{
private IInjectable _interfaceInjected;
private IInjectable _constructorInjected;
private IInjectable _propertyInjected;
//property allows the setting of a different injectable
public IInjectable PropertyInjected
{
get { return _propertyInjected; }
set { _propertyInjected = value; }
}
//constructor requires the loosely coupled injectable
public EverythingsInjected(IInjectable constructorInjected)
{
//have to set the default with property injected
_propertyInjected = GetIInjectable();
//retain the constructor injected injectable
_constructorInjected = constructorInjected;
//using basic interface injection
_interfaceInjected = GetIInjectable();
}
//retrieves the loosely coupled injectable
private IInjectable GetIInjectable()
{
return IInjectableFactory.StaticInjectable;
}
//method that consumes the injectables
public void PrintInjectables()
{
_interfaceInjected.DoSomething("Interface Injected");
_constructorInjected.DoSomething("Constructor Injected");
_propertyInjected.DoSomething("PropertyInjected");
}
}
//the "fake" injectable
public class TestInjectable : IInjectable
{
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", -10000, myStr + " For TEST");
}
}
The above is a complete console program that you can run and play with to see how this works. I tried to keep it simple, but feel free to ask me any questions you have.
Second Edit:
From the comments, it became clear that this was an operational need, not a testing need, so in effect it was a cache. Here is some code that will work for the intended purpose. Again, the below code is a full working console program.
class Program
{
static void Main(string[] args)
{
ServiceFactory factory = new ServiceFactory(false);
//first call hits the webservice
GetServiceQuestions(factory);
//hists the cache next time
GetServiceQuestions(factory);
//can refresh on demand
factory.ResetCache = true;
GetServiceQuestions(factory);
Console.Read();
}
//where the call to the "service" happens
private static List<Question> GetServiceQuestions(ServiceFactory factory)
{
var myFirstService = factory.GetSATService();
var firstServiceQuestions = myFirstService.GetAllQuestions();
foreach (Question question in firstServiceQuestions)
{
Console.WriteLine(question.Text);
}
return firstServiceQuestions;
}
}
//this stands in place of your xml file
public static class DataStore
{
public static List<Question> Questions;
}
//a simple question
public struct Question
{
private string _text;
public string Text { get { return _text; } }
public Question(string text)
{
_text = text;
}
}
//the contract for the real and fake "service"
public interface ISATService
{
List<Question> GetAllQuestions();
}
//hits the webservice and refreshes the store
public class ServiceWrapper : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From WebService");
//this would be your webservice call
DataStore.Questions = new List<Question>()
{
new Question("How do you do?"),
new Question("How is the weather?")
};
//always return from your local datastore
return DataStore.Questions;
}
}
//accesses the data store for the questions
public class FakeService : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From Fake Service (cache):");
return DataStore.Questions;
}
}
//The object that decides on using the cache or not
public class ServiceFactory
{
public bool ResetCache{ get; set;}
public ServiceFactory(bool resetCache)
{
ResetCache = resetCache;
}
public ISATService GetSATService()
{
if (DataStore.Questions == null || ResetCache)
return new ServiceWrapper();
else
return new FakeService();
}
}
Hope this helps. Good luck!
when you say fake the call, are you just testing the client side?
you could use fiddler, intercept the request and return the local xml file to the client. No messing around with your client code then.
To elaborate on Audie's answer
Using DI would get you what you want. Very simply you would create an interface that your real object and your mock object both implement
public interface IFoo
{}
Then you would have your GetSATService method return either a MockSATSerivce or the real SATService object based on your needs.
This is where you would use a DI container (some object that stores interface to concrete type mappings) You would bootstrap the container with the types you want. So, for a unit test, you could contrstruct a mock container that registers the MockSATService as the implementer of the IFoo interface.
Then you would as the container for the concrete type but interface
IFoo mySATService = Container.Resolve<IFoo>();
Then at runtime you would just change out the container so that it bootstraps with the runtime types instead of the mock types but you code would stay the same (Because you are treating everything as IFoo instead SATService)
Does that make sense?
Over time I found that an interesting way to do this is by extracting an interface and creating a wrapper class. This adapts well to a IoC container and also works fine without one.
When testing, create the class passing a fake service. When using it normally, just call the empty constructor, which might simply construct a provider or resolve one using a config file.
public DataService : IDataService
{
private IDataService _provider;
public DataService()
{
_provider = new RealService();
}
public DataService(IDataService provider)
{
_provider = provider;
}
public object GetAllQuestions()
{
return _provider.GetAllQuestions();
}
}

Categories