Test code looks something like this
if (table.ContainsColumn("DecisionGroupOptionId"))
{
foreach (var tableRow in table.Rows)
{
try
{
var name = tableRow["DecisionGroupOptionId"];
var code = _catalogLookupContext.DecisionGroupOptions.FindIdByName(name);
tableRow["DecisionGroupOptionId"] = code;
}
catch (Exception)
{
//don't fail
}
}
}
public virtual string FindIdByName(string name)
{
var item = _list.FirstOrDefault(r => r.Name == name);
Assert.That(item, Is.Not.Null, "ID lookup by the name '{0}' failed. No such name exists in the map.", name);
return item.Id;
}
Testlog output :
Failed : org.test.Test.Silverthread.test1
ID lookup by the name '' failed. No such name exists in the map.
Expected: not null
But was: null
at org.test.Test.SilverThread.FindIdByName(String name) in IdLookup.cs:line
160
The testlog shows failure if 'name' is null.
Isnt this not supposed to show failure as there is catch block? Please help.
Test project uses assemblies like below
[SpecFlow] SpecFlow.Tools.MsBuild.Generation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41
[SpecFlow] TechTalk.SpecFlow, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41
[SpecFlow] TechTalk.SpecFlow.Generator, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41
[SpecFlow] TechTalk.SpecFlow.Utils, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41
[SpecFlow] TechTalk.SpecFlow.Parser, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41
[SpecFlow] TechTalk.SpecFlow.NUnit.Generator.SpecFlowPlugin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=0778194805d6db41
I'm working on xamarin.android and I get this error when a package downloaded a dependent package with existing class
public class DeliveriesFragment : Android.Support.V4.App.ListFragment
{
public override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
}
as you can see I fully typed the class with its namespace
Android.Support.V4.App.ListFragment
but I still get this error
The type 'ListFragment' exists in both 'Xamarin.Android.Support.Fragment, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' and 'Xamarin.Android.Support.v4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
any idea how to fix this? thanks
Good evening everyone.
Currently, I'm new person in IoC/DI. I have a Winform project with C#. Please view some codes and help me resolve below issue:
1/ IRepository
namespace Framework.Repositories
{
public interface IRepository<T> : IDisposable where T:class
{
T Get(int id);
IEnumerable<T> GetAll();
IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
}
}
2/ Repository
namespace Framework.Repositories
{
public class Repository<T> : IRepository<T> where T : class
{
private bool _disposed = false;
private static bool _isTransactionStarted;
protected readonly DbContext Context;
private DbContextTransaction _transaction { get; set; }
public Repository(DbContext context)
{
Context = context;
_isTransactionStarted = false;
if (context == null)
throw new NullReferenceException(nameof(context));
if (Context.Set<T>() == null)
throw new NullReferenceException("_context.Set<T>()");
}
public T Get(int id) => Context.Set<T>().Find(id);
public IEnumerable<T> GetAll() => Context.Set<T>().ToList();
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate) => Context.Set<T>().Where(predicate);
}
}
3/ Model
namespace PRO.Model
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Employee")]
public partial class Employee
{
[Key]
public long EmpId { get; set; }
[StringLength(15)]
public string Username { get; set; }
public string Password { get; set; }
[StringLength(50)]
public string UserGroup { get; set; }
[Required]
[StringLength(50)]
public string FirstName { get; set; }
[StringLength(50)]
public string LastName { get; set; }
[Required]
[StringLength(1)]
public string EmpStatus { get; set; }
}
}
4/ IEmployeeRepository
namespace PRO.Repositories
{
public interface IEmployeeRepository:IRepository<Employee>
{
Employee UserLogin(string username, string password);
}
}
5/ EmployeeRepository
namespace PRO.Repositories
{
public class EmployeeRepository : Repository<Employee>,IEmployeeRepository
{
public EmployeeRepository(DbContext context) : base(context)
{
}
public Employee UserLogin(string username, string password)
{
try
{
return Find(x=>x.Username == username && x.Password == password && x.EmpStatus == BooleanType.Yes ).FirstOrDefault();
}
catch (Exception ex)
{
throw new RepositoryException(ex);
}
}
public MyDbContext myDbContext => Context as MinhTamHotelDbContext;
}
}
6/ IEmployeeService
namespace PRO.Services
{
public interface IEmployeeService
{
Employee UserLogin(string username, string password);
}
}
7/ EmployeeService
namespace PRO.Services
{
public class EmployeeService : IEmployeeService
{
public IEmployeeRepository EmployeeRepos { get; set; }
public Employee UserLogin(string username, string password)
{
return EmployeeRepos.UserLogin(username, password);
}
}
}
8/ DbContext
namespace PRO.Repositories
{
using System.Data.Entity;
public partial class MyHotelDbContext: DbContext
{
public MyHotelDbContext()
: base("name=MyHotelDbContext")
{
}
public virtual DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//DbContext Here
}
}
}
9/App.config
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<connectionStrings>
<add name="MinhTamHotelDbContext" connectionString="data source=.;initial catalog=WiF;persist security info=True;user id=sa;password=#success#;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
<alias alias="transient" type="Microsoft.Practices.Unity.TransientLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="perResolve" type="Microsoft.Practices.Unity.PerResolveLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="AreaRepository" type="PRO.Repositories.AreaRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IAreaRepository" type="PRO.Repositories.IAreaRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="EmployeeRepository" type="PRO.Repositories.EmployeeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IEmployeeRepository" type="PRO.Repositories.IEmployeeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="GnrlCodeRepository" type="PRO.Repositories.GnrlCodeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IGnrlCodeRepository" type="PRO.Repositories.IGnrlCodeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="AreaService" type="PRO.Services.AreaService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IAreaService" type="PRO.Services.IAreaService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="EmployeeService" type="PRO.Services.EmployeeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IEmployeeService" type="PRO.Services.IEmployeeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="GnrlCodeService" type="PRO.Services.GnrlCodeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IGnrlCodeService" type="PRO.Services.IGnrlCodeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IRepository" type="Framework.Repositories.IRepository, Framework.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="Repository" type="Framework.Repositories.Repository, Framework.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<container>
<register type="IAreaRepository" mapTo="AreaRepository">
<lifetime type="perResolve" />
</register>
<register type="IEmployeeRepository" mapTo="EmployeeRepository">
<lifetime type="perResolve" />
</register>
<register type="IGnrlCodeRepository" mapTo="GnrlCodeRepository">
<lifetime type="perResolve" />
</register>
<register type="IEmployeeService" mapTo="EmployeeService">
<property name="EmployeeRepos" dependencyType="IEmployeeRepository" />
<lifetime type="perResolve" />
</register>
<register type="IGnrlCodeService" mapTo="GnrlCodeService">
<property name="GnrlCodeRepos" dependencyType="IGnrlCodeRepository" />
<lifetime type="perResolve" />
</register>
<register type="IAreaService" mapTo="AreaService">
<property name="AreaRepos" dependencyType="IAreaRepository" />
<lifetime type="perResolve" />
</register>
</container>
10/ In my login form
public partial class UserLogin : Form
{
private IEmployeeService _employeeSvr = null;
public IEmployeeService EmployeeSrv
{
get { return _employeeSvr ?? (_employeeSvr = UnityInstanceProvider.CreateInstance<IEmployeeService>()); }
set { _employeeSvr = value; }
}
private void btnLogin_Click(object sender, System.EventArgs e)
{
try
{
this.Cursor = Cursors.WaitCursor;
var employee = EmployeeSrv.UserLogin(txtUsername.Text.TrimEx(), txtPassword.Text.TrimEx());
//MsgBox.ShowInfoMsg(employee.ToJsonObject().ToStringEx());
if (employee != null)
{
Visible = false;
AreaMap.Instance.Show();
}
}
catch (Exception ex)
{
ex.ExceptionHandler();
}
finally
{
this.Cursor = Cursors.Default;
}
}
}
My Error is:
Resolution of the dependency failed, type = "PRO.Services.IEmployeeService", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type DbConnection does not have an accessible constructor.
-----------------------------------------------
At the time of the exception, the container was:
Resolving PRO.Services.EmployeeService,(none) (mapped from PRO.Services.IEmployeeService, (none))
Resolving value for property EmployeeService.EmployeeRepos
Resolving PRO.Repositories.EmployeeRepository,(none) (mapped from PRO.Repositories.IEmployeeRepository, (none))
Resolving parameter "context" of constructor PRO.Repositories.EmployeeRepository(System.Data.Entity.DbContext context)
Resolving System.Data.Entity.DbContext,(none)
Resolving parameter "existingConnection" of constructor System.Data.Entity.DbContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, System.Boolean contextOwnsConnection)
Resolving System.Data.Common.DbConnection,(none)
Somebody can help me resolve this problem ?
In case Unity doesn't support multiple inheritance (EmployeeRepository: Repository, IEmployeeRepository), Have another way to replace Unity ?
Thank you so much
I have two interfaces that says if a service have to be singleton or transient:
public interface ITransient {}
public interface ISingleton {}
I implement this interfaces in other interfaces and classes:
public interface ISession : ISingleton
{
int? UserId {get;set;}
}
public class Session : ISession
{
public int? UserId {get;set;}
}
Then I inject Session in others services:
public interface IBookService : ITransient
{
...
}
public class BookService : IBookService
{
public BookService(ISession session) { ... }
...
}
How to configure StructureMap to make that all instance requests of types that implements ISingleton have to create with Singleton lifecycle??
I have tried it:
Container.Configure(conf => {
conf.For<ITransient>().Transient();
conf.For<ISingleton>().Singleton();
}
But nothing ... don't work, create a Session object as Transient.
I have tried it too:
Container.Configure(conf =>
{
conf.Scan(s =>
{
s.Assembly(assembly);
s.LookForRegistries();
s.AddAllTypesOf<ISingletonDependency>();
s.AddAllTypesOf<ITransientDependency>();
});
conf.For<ITransientDependency>().Transient();
conf.For<ISingletonDependency>().Singleton();
});
And nothing ...
I have seen how to do it using Windsor Castle:
context.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.IncludeNonPublicTypes()
.BasedOn<ITransient>()
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestyleTransient()
);
//Singleton
context.IocContainer.Register(
Classes.FromAssembly(context.Assembly)
.IncludeNonPublicTypes()
.BasedOn<ISingleton>()
.WithService.Self()
.WithService.DefaultInterfaces()
.LifestyleSingleton()
But I don't know how to do using StructureMap ...
Other posibility is using conventions (IRegistrationConvention), but I don't know how to do, example:
public class LifecycleConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (type.GetInterface(typeOf(ISingleton) != null)
**???? what to do ??!!**
}
}
Somebody can help me please?
UPDATE
I have build a convention:
public class BasicConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (!type.IsAbstract && typeof(ISingleton).IsAssignableFrom(type))
{
registry.For(type, new SingletonLifecycle());
}
if (!type.IsAbstract && typeof(ITransient).IsAssignableFrom(type))
{
registry.For(type, new TransientLifecycle());
}
}
}
And that seem work but it register each class as plugin type, in this case:
Session => Session [Singleton]
BookService => BookService [Transient]
But if I inject the Session as ISession ... don't found the instance due to ISession is not registered ... But I can use default convetions ... and then work BUT retrieve the instance as transient ...
Calling WhatDoIHave() I can see it:
===============================================================================================================================================================================================================================================================================
PluginType Namespace Lifecycle Description Name
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
....
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISession Paf.Application.Session Transient Paf.Application.Session ('Paf.Application.Session, Paf.Modules.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null') Paf.Application.Session,... (Default)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
.....
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Session Paf.Application Singleton Paf.Application.Session (Default)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
...
===============================================================================================================================================================================================================================================================================
Can I solve this it?
Ok, I have gone to StructureMap sources to see how to work the default contention.
I found DefaultConventionScanner class:
public class DefaultConventionScanner : ConfigurableRegistrationConvention
{
public override void Process(Type type, Registry registry)
{
if (!type.IsConcrete()) return;
var pluginType = FindPluginType(type);
if (pluginType != null && type.HasConstructors())
{
registry.AddType(pluginType, type);
ConfigureFamily(registry.For(pluginType));
}
}
public virtual Type FindPluginType(Type concreteType)
{
var interfaceName = "I" + concreteType.Name;
return concreteType.GetInterfaces().FirstOrDefault(t => t.Name == interfaceName);
}
}
I can deduce that I could change the plugin type registration (registry.AddType(pluginType, type) line of code) and write it:
if(typeof(ISingleton).IsAssignableFrom(type))
registry.For(pluginType).Use(type).Singleton();
else if (typeof(ITransient).IsAssignableFrom(type))
registry.For(pluginType).Use(type).Transient();
else
{
registry.AddType(pluginType, type);
}
ConfigureFamily(registry.For(pluginType));
Ergo, if the pluginType (interface type) is ISingleton or ITransient I registry the new plugin type as Singleton or Transient otherwise registry the pluginType as allwais.
I have try and know work!! yeah!
Only one consideration, I don't know if exists some diference between:
registry.AddType(pluginType, type);
and:
registry.For(pluginType).Use(type);
I have compare the results of WhaDoIHave() before and after, and I can see a only one difference.
Old result:
===============================================================================================================================================================================================================================================================================
PluginType Namespace Lifecycle Description Name
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISession Paf.Application.Session Transient Paf.Application.Session ('Paf.Application.Session, Paf.Modules.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null') Paf.Application.Session,... (Default)
===============================================================================================================================================================================================================================================================================
New result:
===============================================================================================================================================================================================================================================================================
PluginType Namespace Lifecycle Description Name
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ISession Paf.Application.Session Singleton Paf.Application.Session (Default)
===============================================================================================================================================================================================================================================================================
The new result is Ok, is Singleton, the diference is only in description, I think is no important think.
UPDATE
According to conversation with Steve in the comments of my question, I have decide not use ITransient and ISingleton interfaces. I have decided to use Attributes in the implementation classes.
I've created 2 attributes:
[AttributeUsage(AttributeTargets.Class)]
public class SingletonLifecycleAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class TransientLifecycleAttribute : Attribute
{
}
And I've assiged its to my classes:
public interface ISession { int? UserId {get;set;} }
[SingletonLifecycle]
public class Session : ISession { public int? UserId {get;set;} }
public interface IBookService { ... }
[TransientLifecycle]
public class BookService : IBookService { public BookService(ISession session) { ... } }
Then I have modified my convention:
public class BasicConvention : ConfigurableRegistrationConvention
{
public override void Process(Type type, Registry registry)
{
if (!type.IsConcrete()) return;
var pluginType = FindPluginType(type);
if (pluginType != null && type.HasConstructors())
{
var ci = registry.For(pluginType).Use(type);
if (type.GetCustomAttributes(true).FirstOrDefault(a => a is TransientLifecycleAttribute) != null)
ci.Transient();
if (type.GetCustomAttributes(true).FirstOrDefault(a => a is SingletonLifecycleAttribute) != null)
ci.Singleton();
ConfigureFamily(registry.For(pluginType));
}
}
public virtual Type FindPluginType(Type concreteType)
{
var interfaceName = "I" + concreteType.Name;
return concreteType.GetInterfaces().FirstOrDefault(t => t.Name == interfaceName);
}
}
I think all is now fine and better ;)
Thanks Steve!
I am updating my wcf service reference through SvcUtil.exe.
command is as follows:
SvcUtil.exe http://localhost:50886/Service1.svc /n:*,ClassLibrary2.ServiceReference1 /o:Service References\ServiceReference1\Reference.cs /ct:System.Collections.Generic.List`1, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 /config:app.config
And my wcf code is as follows:
==============================================================
namespace WcfService1
{
[ServiceContract]
[ServiceKnownType(typeof(Dictionary<string, string>))]
public interface **IService1**
{
[OperationContract]
string GetData(int value);
// TODO: Add your service operations here
[OperationContract]
string Hello(string value);
}
}
namespace WcfService1
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public string Hello(string value)
{
return string.Format("You entered: {0}", value);
}
}
}
I am using this service in my class library project which name is ClassLibrary1. When i am updating this service through visual studio then in Reference.cs I got following statement:
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="**ServiceReference1.IService1**")]
public interface IService1
But when m updating service through svcutil then I got following statement:
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="**ClassLibrary2.ServiceReference1.IService1**")]
public interface IService1
The difference is configuration name. I didn't understand which command should i used in svcutil to set configuration name just as ServiceReference1.IService1 ?
Please help.
Just by changing [ServiceContract] into [ServiceContract(Name="ServiceReference1.IService1", ConfigurationName="ServiceReference1.IService1")]. See this block post.