Registering and resolving named instances in Castle.Windsor - c#-4.0

I can't seem to be able to get the proper instance injected into a class ctor. Here is what I am trying to do:
class Program
{
static void Main(string[] args)
{
WindsorContainer container = new WindsorContainer();
container.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(() => GetSessionFactory("1"))
.Named("1"),
Component.For<ISessionFactory>()
.UsingFactoryMethod(() => GetSessionFactory("2"))
.Named("2"));
container.Register(
Component.For<IRepository>()
.ImplementedBy<Repository>()
.DependsOn(container.Resolve<ISessionFactory>("1")),
Component.For<IReadOnlyRepository>()
.ImplementedBy<ReadOnlyRepository>()
.DependsOn(container.Resolve<ISessionFactory>("2")));
var connectionString1 = container.Resolve<IRepository>().Factory.ConnectionString;
var connectionString2 = container.Resolve<IReadOnlyRepository>().Factory.ConnectionString;
//These should not be equal!!!
Console.WriteLine(connectionString1);
Console.WriteLine(connectionString2);
}
public static SessionFactory GetSessionFactory(string connectionString)
{
return new SessionFactory { ConnectionString = connectionString };
}
public static bool Blah(Type accepted)
{
int d = 3;
return true;
}
}
public interface ISessionFactory
{
string ConnectionString { get; set; }
}
public class SessionFactory : ISessionFactory
{
public string ConnectionString { get; set; }
}
public interface IRepository
{
ISessionFactory Factory { get; set; }
}
public class Repository : IRepository
{
public ISessionFactory Factory { get; set; }
public Repository(ISessionFactory factory)
{
this.Factory = factory;
}
}
public interface IReadOnlyRepository
{
ISessionFactory Factory { get; set; }
}
public class ReadOnlyRepository : IReadOnlyRepository
{
public ISessionFactory Factory { get; set; }
public ReadOnlyRepository(ISessionFactory factory)
{
this.Factory = factory;
}
}
Can anyone spot the problem?

try this:
container.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(() => GetSessionFactory("1"))
.Named("1"),
Component.For<ISessionFactory>()
.UsingFactoryMethod(() => GetSessionFactory("2"))
.Named("2"),
Component.For<IRepository>()
.ImplementedBy<Repository>()
.DependsOn(Dependency.OnComponent(typeof(ISessionFactory),"1")),
Component.For<IReadOnlyRepository>()
.ImplementedBy<ReadOnlyRepository>()
.DependsOn(Dependency.OnComponent(typeof(ISessionFactory), "2")));

Related

ServiceStack - injecting Properties

I am getting very confused with the Funq container.
I have the following:
public interface IConnectionString
{
string ConnectionString { get; set; }
}
public class FoundationConnection : IConnectionString
{
public FoundationConnection(string connectionString)
{
ConnectionString = connectionString;
}
public string ConnectionString { get; set; }
}
Now in my AppHost, I would like to register
container.Register<IConnectionString>(c=> new FoundationConnection(AppSettings.Get(
"FoundationConnectionString", "").MapHostAbsolutePath()));
In my ServiceInterface I want to call this injected method somehow:
public class ServiceInterface : Service
{
public IConnectionString foundationConnection { get; set; }
public object Any(SomeRequest request)
{
string injectedProperty = foundationConnection.ConnectionString;
}
}
}
Issue is that foundationConnection is null and never injected.
I hope this makes sense?
Personally I would use AppSettings to access config settings which would allow you to source configuration from a number of different and cascading configuration sources.
But I've tested this using these types:
public interface IConnectionString
{
string ConnectionString { get; }
}
class FoundationConnectionString : IConnectionString
{
public FoundationConnectionString(string connectionString)
{
ConnectionString = connectionString;
}
public string ConnectionString { get; set; }
}
and it's working correctly after registering it in the AppHost.Configure():
public override void Configure(Container container)
{
container.Register<IConnectionString>(c =>
new FoundationConnectionString("My Connection"));
}
and accessing it from a test service:
[Route("/test")]
public class Test : IReturn<string> { }
public class TestService : Service
{
public IConnectionString Config { get; set; }
public object Any(Test request)
{
return Config.ConnectionString;
}
}
Which returns "My Connection" when called.

An error occured while updating the feature OrchardCMS

I have a problem with my OrchardCMS migrations, the following code fails doing the migration (because I created the ContentItem for illustrative purposes), the error raises creating the content type:
public class Migrations : DataMigrationImpl {
private readonly IContentManager _contentManager;
public Migrations(IContentManager contentManager)
{
_contentManager = contentManager;
}
public int Create() {
SchemaBuilder.CreateTable("MedioPartRecord", table => table
.ContentPartRecord()
.Column<string>("Identificador")
.Column<string>("Matricula")
.Column<string>("NumeroSistemaGPS")
.Column<string>("Observaciones")
.Column("Matriculacion",DbType.DateTime)
.Column<int>("IdTipoMedio")
.Column("InicioTrabajo", DbType.DateTime)
.Column<int>("Kms"));
ContentDefinitionManager.AlterTypeDefinition("TipoMedio", type => type
.Creatable()
.WithPart("TitlePart")
.WithPart("CommonPart"));
ContentDefinitionManager.AlterPartDefinition(typeof(MedioPart).Name, part => part.Attachable());
ContentDefinitionManager.AlterTypeDefinition("Medio", type => type
.Creatable()
.WithPart("CommonPart")
.WithPart("MedioPart")
);
return 1;
}
public class MedioPartRecord : ContentPartRecord {
public virtual string Identificador { get; set; }
public virtual string Matricula { get; set; }
public virtual string NumeroSistemaGPS { get; set; }
public virtual string Observaciones { get; set; }
public virtual DateTime Matriculacion { get; set; }
public virtual DateTime InicioTrabajo { get; set; }
public virtual int IdTipoMedio { get; set; }
public virtual int Kms { get; set; }
}
public class MedioPart : ContentPart<MedioPartRecord>
{
public virtual int IdTipoMedio { get { return Record.IdTipoMedio; } set { Record.IdTipoMedio = value; } }
public virtual string Identificador { get { return Record.Identificador; } set { Record.Identificador = value; } }
public virtual string Matricula { get { return Record.Matricula; } set { Record.Matricula = value; } }
public virtual string NumeroSistemaGPS { get { return Record.NumeroSistemaGPS; } set { Record.NumeroSistemaGPS = value; } }
public virtual string Observaciones { get { return Record.Observaciones; } set { Record.Observaciones = value; } }
public virtual DateTime Matriculacion { get { return Record.Matriculacion; } set { Record.Matriculacion = value; } }
public virtual DateTime InicioTrabajo { get { return Record.InicioTrabajo; } set { Record.InicioTrabajo = value; } }
public virtual int Kms { get { return Record.Kms; } set { Record.Kms = value; } }
}
public class MedioPartHandler : ContentHandler {
public MedioPartHandler(IRepository<MedioPartRecord> repository)
{
Filters.Add(StorageFilter.For(repository));
}
}
Thank you
The problem was that I forgot to set the datetime as nullable type.

Register Custom Generic type in AutoMapper

i want register custo generic type like default generic type that register in autoMaper (like List, Array) in AutoMappper.
i have one generic type in project this Code :
class PagedResult<T>
{
public List<T> PageOfResults { get; set; }
public int TotalItems { get; set; }
}
and Dto Class is:
class StudentDto
{
public int ID { get; set; }
public string Name { get; set; }
}
and VM Model is :
class StudentVM
{
public int ID { get; set; }
public string Name { get; set; }
}
and service class:
class MyServie
{
public PagedResult<StudentDto> Swap()
{
var test2 = new PagedResult<StudentDto>();
test2.PageOfResults = new List<StudentDto>();
test2.PageOfResults.Add(new StudentDto() { ID = 10, Name = "Ten" });
test2.TotalItems = 10;
return test2;
}
}
i want use from AutoMapper Object Manager for register PagedResult<> in automapper but i can not do this
var allMappers = MapperRegistry.AllMappers();
MapperRegistry.AllMappers = () => new IObjectMapper[]{
new IdentifiableMapper(),
}.Concat(allMappers);
var service = new MyServie();
PagedResult<StudentDto> pageableStudentDto = service.Swap();
Mapper.CreateMap<StudentDto, StudentVM>();;
PagedResult<StudentVM> vm = Mapper.Map<PagedResult<StudentDto>, PagedResult<StudentVM>>(pageableStudentDto);
and implement of
public class PageOfMapper : IObjectMapper
{
public bool IsMatch(ResolutionContext context)
{
return typeof(PagedResult<>).IsAssignableFrom(context.SourceType.GetGenericTypeDefinition()) &&
typeof(PagedResult<>).IsAssignableFrom(context.DestinationType.GetGenericTypeDefinition());
//return true;
}
public object Map(ResolutionContext context, IMappingEngineRunner mapper)
{
// please help me in this code for map ******************
return null;
}
}

ServiceStack empty metadata

Seeing a strange problem, getting empty metata pages for xml,json and jvs.
Using the following command line app. How does one debug these issues?
namespace ConsoleApplication2
{
public struct NativeUser
{
public int login;
public string group;
public string name;
}
[DataContract]
public class User
{
private NativeUser _native;
public User() { }
public User(NativeUser native)
{
_native = native;
}
public static implicit operator NativeUser(User user)
{
return user._native;
}
public static implicit operator User(NativeUser native)
{
return new User(native);
}
// ReSharper disable InconsistentNaming
[DataMember]
public int login
{
get { return _native.login; }
set { _native.login = value; }
}
[DataMember]
public string group
{
get { return _native.group; }
set { _native.group = value; }
}
[DataMember]
public string name
{
get { return _native.name; }
set { _native.name = value; }
}
}
[Description("GET account, all or by list of groups or by list of logins")]
[Route("/accounts/{groups}", "GET")]
[Route("/accounts/{logins}", "GET")]
[Route("/accounts/", "GET")]
public class Accounts : IReturn<User[]>
{
public string[] groups { set; get; }
public int[] logins { set; get; }
public Accounts() { }
public Accounts(params int[] logins)
{
this.logins = logins;
}
public Accounts(params string[] groups)
{
this.groups = groups;
}
}
public class Host : AppHostHttpListenerBase
{
public Host() : base("Test",
typeof(Accounts).Assembly)
{
}
public override void Configure(Funq.Container container)
{
}
}
public class Servce : IService
{
public object Get(Accounts request)
{
return new List<User>(){new User(new NativeUser())};
}
}
class Program
{
static void Main(string[] args)
{
var host = new Host();
host.Init();
host.Start("http://+:12345/");
global::System.Console.ReadLine();
}
}
}
Nm, found the bug :
public class Accounts : IReturn<User[]>
needs to be
public class Accounts : IReturn<List<User>>
Another very note worthy thing: All DTO's and objects being passed back and fourth in the DTO's require an empty constructor in order for the metata data to be properly generated.
Not sure if this is by design or a bug

Ninject, passing constructor argument to the kernel

Here is my problem:
I want to pass in one of the values to the constructor every time I request an instance form the kernel. I written some code below to illustrate the problem. The test is not failing so I guess that this works, but it does look pretty ugly. Is there a better, cleaner way to accomplish this with Ninject? Or should I rethink my design? All suggestions are appreciated.
[TestFixture]
public class Sandbox
{
[Test]
public void Run_Forrest_Run()
{
using (var kernel = new StandardKernel(new Module()))
{
var connection = new Connection(Guid.NewGuid().ToString());
var downloader = kernel.Get<IDownloader>(new IParameter[] { new Parameter("connection", connection, false) });
Assert.That(downloader.Connection.Info, Is.EqualTo(connection.Info));
}
}
public class Downloader : IDownloader
{
public Downloader(Connection connection, ILogger logger)
{
Connection = connection;
Logger = logger;
}
public Connection Connection { get; private set; }
public void Download()
{
Logger.Log("Downloading...");
}
public ILogger Logger { get; private set; }
}
public interface IDownloader
{
Connection Connection { get; }
void Download();
}
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.Out.WriteLine(message);
}
}
public interface ILogger
{
void Log(string message);
}
public class Connection
{
public Connection(string info)
{
Info = info;
}
public string Info { get; private set; }
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<ConsoleLogger>();
Bind<IDownloader>().To<Downloader>()
.WithConstructorArgument("connection", context =>
{
var p = context.Parameters.First(x => x.Name == "connection");
return p.GetValue(context, null);
});
}
}
}
If you always want to specify the Connection when resolving a IDownloader then I think the ConstructorArgument (which is a IParameter) is what you are looking for:
[Test]
public void Run_Forrest_Run()
{
using (var kernel = new StandardKernel(new Module()))
{
var connection = new Connection(Guid.NewGuid().ToString());
var downloader = kernel.Get<IDownloader>(new [] {
new ConstructorArgument("connection", connection) });
Assert.That(downloader.Connection.Info, Is.EqualTo(connection.Info));
}
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<ConsoleLogger>();
Bind<IDownloader>().To<Downloader>();
}
}

Resources