structuremap object reference with particular dependency - structuremap4

I am new to structuremap.
I want to get Shopper classes object with either "master" or "visa" dependency based on user input.
In below code I have created two concrete classes MasterCard and Visa from ICreditCard. I am injecting dependency of ICreditCard but when code is executing based on user's option I want to inject MasterCard or Visa depdency to Shopper class and get reference of that Shopper class object.
Can someone tell me how to do it if it is possible. I also want to know if I want to initialise object in some other class then how to do it(is it by exposing a method returning container object?)
class Program
{
static void Main(string[] args)
{
var container = new Container();
container.Configure(c => c.For<ICreditCard>().Use<MasterCard>().Named("master"));
container.Configure(x => x.For<ICreditCard>().Use<Visa>().Named("visa"));
//how to get instance of Shopper with master card object reference?
Console.ReadKey();
}
public class Visa : ICreditCard
{
public string Charge()
{
return "Visa... Visa";
}
public int ChargeCount
{
get { return 0; }
}
}
public class MasterCard : ICreditCard
{
public string Charge()
{
ChargeCount++;
return "Charging with the MasterCard!";
}
public int ChargeCount { get; set; }
}
public interface ICreditCard
{
string Charge();
int ChargeCount { get; }
}
public class Shopper
{
private readonly ICreditCard creditCard;
public Shopper(ICreditCard creditCard)
{
this.creditCard = creditCard;
}
public int ChargesForCurrentCard
{
get { return creditCard.ChargeCount; }
}
public void Charge()
{
Console.WriteLine(creditCard.Charge());
}
}
}

Related

autofac not resolve properly generic List type

I am trying to resolve list of object using autofac Container, and expecting an empty list in response. However, I am not able to get empty list in return instead getting count as 1.
I also try with without list registration in aotufac conatiner but getting same response.
<pre><code>
class autofacFactory : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>));
builder.RegisterType<Response>().As<IResponse>();
builder.RegisterType<CustomDependencyResolver>().As<ICustomDependencyResolver>();
}
}
public class Response : IResponse
{
public string TransactionNo { get; set; }
public string SchemeCode { get; set; }
}
public interface IResponse
{
string TransactionNo { get; set; }
string SchemeCode { get; set; }
}
public interface ICustomDependencyResolver
{
TResolved Resolve<TResolved>();
}
internal class CustomDependencyResolver : ICustomDependencyResolver
{
private readonly ILifetimeScope _lifetimeScope;
public CustomDependencyResolver(ILifetimeScope lifetimeScope)
{
_lifetimeScope = lifetimeScope;
}
public TResolved Resolve<TResolved>()
=> _lifetimeScope.Resolve<TResolved>();
}
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterModule(new autofacFactory());
using (var container = builder.Build())
{
ICustomDependencyResolver customDependencyResolver = container.Resolve<ICustomDependencyResolver>();
var collection = customDependencyResolver.Resolve<ICollection<IResponse>>();
var list = customDependencyResolver.Resolve<IList<IResponse>>();
}
}
Actual response:
[Image1][1]
[Image2][2]
[Expected Response][3]
[1]: https://i.stack.imgur.com/NVXeW.jpg
[2]: https://i.stack.imgur.com/k58QX.jpg
[3]: https://i.stack.imgur.com/EcFyc.jpg
Try not registering IList<> or List<> - Autofac has built-in support for that.

inherited class AutoMapper.AutoMapperMappingException

I am new at automapper and it is a very good stuff easy to use, but now I have a problem with it. Trying to convert my derived class to base and it gives me
AutoMapper.AutoMapperMappingException
Missing type map configuration or unsupported mapping.
Mapping types: ClientEventDb -> EventId
Database.ClientEventDb -> EventId
Destination path: ClientEvent
Source value:
Event:Login
Automapper wants to convert ClientEventDb to EventId? I don't understand why. EventId is an enum...
Please help me I have run out of ideas.
Here is the code which I run:
ClientEventDb[] edbl;
using (var context = new DbEntities())
{
edbl=context.Events.Take(1000).ToArray();
}
Mapper.CreateMap<ClientEventDb, ClientEvent>();
Console.WriteLine("hello");
return edbl.Select(edb => Mapper.Map<ClientEvent>(edb)).ToArray();
Here are my classes
[Table("events", Schema = "public")]
public class ClientEventDb : ClientEvent
{
public ClientEventDb(string userName, EventId happening, object userObject = null)
: base(userName, happening, userObject)
{
}
public ClientEventDb()
{
}
}
[ProtoContract]
[Table("events", Schema = "public")]
public class ClientEvent : ClientEventBase
{
[ProtoMember(1)]
[Column("username")]
public string UserName { get; private set; }
[ProtoMember(2)]
[Column("time")]
public DateTime DateTime { get; private set; }
[ProtoMember(3)]
[Key]
[Column("id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get; private set; }
[ProtoMember(4)]
[Column("data")]
public byte[] UserObject { get; set; }
public ClientEvent(string userName,EventId happening, object userObject=null) : base(happening)
{
UserName = userName;
DateTime = DateTime.Now;
//UserObject = null;
if (userObject!=null) throw new NotImplementedException();
}
public ClientEvent()
{
}
protected ClientEvent Clone()
{
return (ClientEvent)MemberwiseClone();
}
}
[ProtoContract]
[ProtoInclude(10, typeof(ClientEvent))]
public class ClientEventBase
{
[Column("eventid")]
[ProtoMember(1)]
public int EventIdValue { get; set; } //must be public because of entity framework
[NotMapped]
public EventId EventId
{
get { return (EventId) EventIdValue; }
set { EventIdValue = (int) value; }
}
public ClientEventBase(EventId eventId)
{
EventId = eventId;
}
public ClientEventBase()
{
}
public override string ToString()
{
return String.Format("Event:{0}",EventId);
}
}
public enum EventId
{
Login = 1,
Logout,
ExitApplication,
}
UPDATE
bugfix: ClientEvent [Key] attribute moved to id property
Solution was this (thx to stuartd):
ClientEventDb[] edbl;
using (var context = new DbEntities())
{
edbl=context.Events.ToArray();
}
Mapper.CreateMap<ClientEventDb, ClientEvent>().ConstructUsing((ClientEventDb src) => new ClientEvent());
return edbl.Select(Mapper.Map<ClientEvent>).ToArray();
AutoMapper is confused as its made to map between similar properties in different classes, you are using it incorrectly - you just need to go from the derived class to the base which does not require AutoMapper. You could use this to do what you need....
ClientEventDb[] edbl;
using (var context = new DbEntities())
{
edbl=context.Events.Take(1000).ToArray();
}
return edbl.Cast<ClientEvent>().ToList();
I'd be looking at why you even feel you need a derived ClientEventDb though - understand we dont have the whole picture here but it seems to do nothing in addition to what the base class already does.
The issue is that ClientEvent has two constructors but you have not told AutoMapper which to use.
If you want it to use your constructor with parameters, change your mapping code to this and it will work:
Mapper.CreateMap<ClientEventDb, ClientEvent>()
.ConstructUsing(src => new ClientEvent(src.UserName, src.EventId));
Or to make AutoMapper use the default constructor:
Mapper.CreateMap<ClientEventDb, ClientEvent>()
.ConstructUsing((ClientEventDb src) => new ClientEvent());

Does ServiceStack support generics in end-to-end typed requests

I was playin' around with ServiceStack and was wondering if it supported this scenario. I'm using generics in my request types so that many DTOs that inherit from a common interface will support the same basic methods [ like... GetById(int Id) ].
Using a request type specific to a single kind of DTO works, but breaks the generics nice-ness...
var fetchedPerson = client.Get<PersonDto>(new PersonDtoGetById() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson.Id)); //PASS
Mapping a route to the generic also works:
Routes.Add<DtoGetById<PersonDto>>("/persons/{Id}", ApplyTo.Get);
...
var fetchedPerson2 = client.Get<PersonDto>(string.Format("/persons/{0}", person.Id));
Assert.That(person.Id, Is.EqualTo(fetchedPerson2.Id)); //PASS
But using the end-to-end generic request type fails:
var fetchedPerson3 = client.Get<PersonDto>(new DtoGetById<PersonDto>() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson3.Id)); //FAIL
I wonder if I'm just missing something, or if i'm trying to abstract just ooone layer too far... :)
Below is a complete, failing program using NUnit, default ServiceStack stuff:
namespace ssgenerics
{
using NUnit.Framework;
using ServiceStack.ServiceClient.Web;
using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;
using ServiceStack.WebHost.Endpoints;
[TestFixture]
class Program
{
public static PersonDto GetNewTestPersonDto()
{
return new PersonDto()
{
Id = 123,
Name = "Joe Blow",
Occupation = "Software Developer"
};
}
static void Main(string[] args)
{}
[Test]
public void TestPutGet()
{
var listeningOn = "http://*:1337/";
var appHost = new AppHost();
appHost.Init();
appHost.Start(listeningOn);
try
{
var BaseUri = "http://localhost:1337/";
var client = new JsvServiceClient(BaseUri);
var person = GetNewTestPersonDto();
client.Put(person);
var fetchedPerson = client.Get<PersonDto>(new PersonDtoGetById() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson.Id));
var fetchedPerson2 = client.Get<PersonDto>(string.Format("/persons/{0}", person.Id));
Assert.That(person.Id, Is.EqualTo(fetchedPerson2.Id));
Assert.That(person.Name, Is.EqualTo(fetchedPerson2.Name));
Assert.That(person.Occupation, Is.EqualTo(fetchedPerson2.Occupation));
var fetchedPerson3 = client.Get<PersonDto>(new DtoGetById<PersonDto>() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson3.Id));
Assert.That(person.Name, Is.EqualTo(fetchedPerson3.Name));
Assert.That(person.Occupation, Is.EqualTo(fetchedPerson3.Occupation));
}
finally
{
appHost.Stop();
}
}
}
public interface IDto : IReturnVoid
{
int Id { get; set; }
}
public class PersonDto : IDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Occupation { get; set; }
}
public class DtoGetById<T> : IReturn<T> where T : IDto { public int Id { get; set; } }
public class PersonDtoGetById : IReturn<PersonDto> { public int Id { get; set; } }
public abstract class DtoService<T> : Service where T : IDto
{
public abstract T Get(DtoGetById<T> Id);
public abstract void Put(T putter);
}
public class PersonService : DtoService<PersonDto>
{
public override PersonDto Get(DtoGetById<PersonDto> Id)
{
//--would retrieve from data persistence layer
return Program.GetNewTestPersonDto();
}
public PersonDto Get(PersonDtoGetById Id)
{
return Program.GetNewTestPersonDto();
}
public override void Put(PersonDto putter)
{
//--would persist to data persistence layer
}
}
public class AppHost : AppHostHttpListenerBase
{
public AppHost()
: base("Test HttpListener",
typeof(PersonService).Assembly
) { }
public override void Configure(Funq.Container container)
{
Routes.Add<DtoGetById<PersonDto>>("/persons/{Id}", ApplyTo.Get);
}
}
}
No, It's a fundamental concept in ServiceStack that each Service requires its own unique Request DTO, see this answer for more examples on this.
You could do:
[Route("/persons/{Id}", "GET")]
public class Persons : DtoGetById<Person> { ... }
But I strongly advise against using inheritance in DTOs. Property declaration is like a DSL for a service contract and its not something that should be hidden.
For more details see this answer on the purpose of DTO's in Services.

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

How to define a constraint on class type if It has custom attribute?

there is any way to force a class to implement an interface , if It has an specific custom attribute?
I want to have a compile time error , if the class with specific attribute does not implement an specific interface.
[myAttrib]
public MyClass:IMyInterface
{
}
If myClass is not typeof(IMyInterface) , I will get an error in compile time.
thanks,
In case of properties, You could create an abstract class inheriting the interface and gets your final class drive from that abstract class.
Have a look at
public interface Test
{
string Name { get; set; }
}
public abstract class Test1 : Test
{
public abstract string Name { get; set; }
}
public class Test2 : Test1
{
}
For custom attribute you could do
public class Alias : System.Attribute
{
string[] _types;
public Alias(params string[] types)
{
this.Types = types;
}
public Alias()
{
this.Types = null;
}
public string[] Types
{
get { return _types; }
set { _types = value; }
}
}
public interface Test
{
Alias Attrib{ get;}
}
public abstract class Test1 : Test
{
public abstract Alias Attrib { get; }
}
public class Test2 : Test1
{
}
Hope I answer your question.

Resources